乐趣区

关于harmonyos:HarmonyOS实现表单页面的输入必填校验和提交

一. 样例介绍
本篇 Codelab 基于 input 组件、label 组件和 dialog 组件,实现表单页面的输出、必填校验和提交:
1.  为 input 组件设置不同类型(如:text,email,date 等),实现表单页面。
2.  对表单页面中的用户名、电子邮件、喜好输入框进行必填校验。
3.  应用弹框抉择性别、喜好。

相干概念
● input 组件:交互式组件,包含单选框,多选框,按钮和单行文本输入框。
● label 组件:为 input、button、textarea 组件定义相应的标注,点击该标注时会触发绑定组件的点击成果。
● dialog 组件:自定义弹窗容器。

残缺示例
gitee 源码地址

二. 环境搭建
咱们首先须要实现 HarmonyOS 开发环境搭建,可参照如下步骤进行。

软件要求
● DevEco Studio 版本:DevEco Studio 3.1 Release 及以上版本。
● HarmonyOS SDK 版本:API version 9 及以上版本。

硬件要求

● 设施类型:华为手机或运行在 DevEco Studio 上的华为手机设施模拟器。
● HarmonyOS 零碎:3.1.0 Developer Release 及以上版本。

环境搭建
1.  装置 DevEco Studio,详情请参考下载和装置软件。
2.  设置 DevEco Studio 开发环境,DevEco Studio 开发环境须要依赖于网络环境,须要连贯上网络能力确保工具的失常应用,能够依据如下两种状况来配置开发环境:
● 如果能够间接拜访 Internet,只需进行下载 HarmonyOS SDK 操作。
● 如果网络不能间接拜访 Internet,须要通过代理服务器才能够拜访,请参考配置开发环境。
1.  开发者能够参考以下链接,实现设施调试的相干配置:
● 应用真机进行调试
● 应用模拟器进行调试

三. 代码构造解读
本篇 Codelab 只对外围代码进行解说,对于残缺代码,咱们会在源码下载或 gitee 中提供。

├──entry/src/main/js                          // 代码区
│  └──MainAbility   
│     ├──common
│     │  ├──constant
│     │  │  └──commonConstants.js             // 公共常量
│     │  └──images                            // 图片资源目录
│     ├──i18n
│     │  ├──en-US.json                          // 英文国际化
│     │  └──zh-CN.json                          // 中文国际化
│     ├──pages
│     │  └──index
│     │     ├──index.css                      // 表单页面款式
│     │        ├──index.hml                      // 表单页面
│     │        └──index.js                       // 表单页面逻辑
│     └──app.js                               // 程序入口
└──entry/src/main/resource                    // 利用动态资源目录

四. 页面设计
页面包含用户名、电子邮箱、出生日期、身高、性别、喜好输入框和提交按钮,点击提交按钮进行必填校验。

<!-- index.hml -->
<div class="container">
    ...
    <div class="user-area">
        <image class="image" src="{{urls.user}}"></image>
        <div class="input-label">
            <image src="{{urls.required}}"></image>
            <label class="label" target="user">{{$t('strings.user') }}</label>
        </div>
        <div class="input-div">
            <input class="input" id="user" type="text" placeholder="{{$t('strings.user') }}" onchange="inputChange"
                   ontranslate="translate"></input>
        </div>
    </div>
    <div class="input-area">
        <image src="{{urls.email}}"></image>
        <div class="input-label">
            <image src="{{urls.required}}"></image>
            <label class="label" target="email">{{$t('strings.email') }}</label>
        </div>
        <div class="input-div">
            <input class="input" id="email" type="email" placeholder="{{$t('strings.email') }}"
                   onchange="inputChange">
            </input>
        </div>
    </div>
    <div class="input-area">
        <image src="{{urls.date}}"></image>
        <div class="input-label">
            <label class="label" target="date">{{$t('strings.birthday') }}</label>
        </div>
        <div class="input-div">
            <input class="input" id="date" type="date" placeholder="{{$t('strings.date') }}" onchange="inputChange">
            </input>
        </div>
    </div>
    <div class="input-area">
        <image src="{{urls.height}}"></image>
        <div class="input-label">
            <label class="label" target="height">{{$t('strings.height_holder') }}</label>
        </div>
        <div class="input-div">
            <input class="input" id="height" type="number" placeholder="{{$t('strings.height') }}"
                   onchange="inputChange"></input>
        </div>
    </div>
    <div class="input-area">
        <image src="{{urls.gender}}"></image>
        <div class="input-label">
            <label class="label" target="gender">{{$t('strings.gender') }}</label>
        </div>
        <div class="input-div" onclick="openGender">
            <input class="input select" id="gender" type="text" placeholder="{{$t('strings.gender') }}"
                   softkeyboardenabled="false"
                   value="{{genderObj[gender] }}"></input>
            <image src="{{urls.spinner}}"></image>
        </div>
    </div>
    <div class="input-area">
        <image src="{{urls.hobby}}"></image>
        <div class="input-label">
            <image src="{{urls.required}}"></image>
            <label class="label" target="hobbies">{{$t('strings.hobbies') }}</label>
        </div>
        <div class="input-div" onclick="openHobby">
            <input class="input select" id="hobbies" type="text" placeholder="{{$t('strings.hobby') }}"
                   softkeyboardenabled="false" value="{{hobbies.join(',') }}"></input>
            <image src="{{urls.spinner}}"></image>
        </div>
    </div>
    <button type="capsule" onclick="buttonClick">{{$t('strings.submit') }}</button>
    ...
</div>

成果如图所示:

点击性别输入框弹出性别单选框,点击喜好输入框弹出喜好多选框。

<!-- index.hml -->
<div class="container">
    ...
    <dialog id="genderDialog">
        <div class="gender-dialog">
            <text>{{$t('strings.gender_select') }}</text>
            <div>
                <text>{{$t('strings.gender_male') }}</text>
                <input if="{{gender === 0}}" class="radio" type="radio" checked="true" name="radio"
                       value="{{$t('strings.gender_male') }}" onchange="onRadioChange"></input>
                <input if="{{gender === 1}}" class="radio" type="radio" checked="false" name="radio"
                       value="{{$t('strings.gender_male') }}" onchange="onRadioChange"></input>
            </div>
            <divider vertical="false"></divider>
            <div>
                <text>{{$t('strings.gender_female') }}</text>
                <input if="{{gender === 0}}" class="radio" type="radio" checked="false" name="radio"
                       value="{{$t('strings.gender_female') }}"></input>
                <input if="{{gender === 1}}" class="radio" type="radio" checked="true" name="radio"
                       value="{{$t('strings.gender_female') }}"></input>
            </div>
            <div class="button">
                <text onclick="closeGender">{{$t('strings.cancel') }}</text>
                <divider vertical="true"></divider>
                <text onclick="confirmGender">{{$t('strings.determined') }}</text>
            </div>
        </div>
    </dialog>
    <dialog id="hobbyDialog">
        <div class="hobby-dialog">
            <text>{{$t('strings.hobby') }}</text>
            <div>
                <text>{{$t('strings.hobby_swim') }}</text>
                <input class="checkbox" type="checkbox" checked="{{hobbies.indexOf(hobbiesOjb[0]) !== -1 }}"
                       value="{{hobbiesOjb[0] }}" onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_fitness') }}</text>
                <input class="checkbox" type="checkbox" checked="{{hobbies.indexOf(hobbiesOjb[1]) !== -1 }}"
                       value="{{hobbiesOjb[1] }}" onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_soccer') }}</text>
                <input class="checkbox" type="checkbox" checked="{{hobbies.indexOf(hobbiesOjb[2]) !== -1 }}"
                       value="{{hobbiesOjb[2] }}" onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_basketball') }}</text>
                <input class="checkbox" type="checkbox" checked="{{hobbies.indexOf(hobbiesOjb[3]) !== -1 }}"
                       value="{{hobbiesOjb[3] }}" onchange="checkboxOnChange"></input>
            </div>
            <div>
                <text>{{$t('strings.hobby_reading_book') }}</text>
                <input class="checkbox" type="checkbox" checked="{{hobbies.indexOf(hobbiesOjb[4]) !== -1 }}"
                       value="{{hobbiesOjb[4] }}" onchange="checkboxOnChange"></input>
            </div>
            <div class="button">
                <text onclick="closeHobby">{{$t('strings.cancel') }}</text>
                <divider vertical="true"></divider>
                <text onclick="confirmHobby">{{$t('strings.determined') }}</text>
            </div>
        </div>
    </dialog>
</div>

成果如图所示:

五. 后盾逻辑解决
用户名、电子邮箱、出生日期、身高输入框中值发生变化时,会在 data 对象中实时更新。

// index.js
export default {
  data: {
    ...
    user: '',
    email: '',
    date: '',
    height: '',
    ...
  },
  ...
  // 实时保留输入框内容
  inputChange(event) {
    let idName = event.target.id;
    if (idName === CommonConstants.USER) {this.user = event.value;} else if (idName === CommonConstants.EMAIL) {this.email = event.value;} else if (idName === CommonConstants.DATE) {this.date = event.value;} else if (idName === CommonConstants.HEIGHT) {this.height = event.value;}
  },
  ...
}

通过自定义弹框抉择性别、喜好。在弹框中点击勾销按钮敞开以后弹框,点击确定按钮先设置所选值再敞开弹框。

// index.js
export default {
  data: {
    ...
    genderObj: [],
    genderTemp: 0,
    gender: 0,
    hobbiesOjb: [],
    hobbiesTemp: [],
    hobbies: []},
  ...
  // 关上性别弹框
  openGender() {this.$element('genderDialog').show();},

  // 从新抉择性别
  onRadioChange(event) {if (event.checked) {this.genderTemp = 0;} else {this.genderTemp = 1;}
  },

  // 敞开性别弹框
  closeGender() {this.$element('genderDialog').close();},

  // 性别弹框中点击“确定”confirmGender() {
    this.gender = this.genderTemp;
    this.closeGender();},

  // 关上喜好弹框
  openHobby() {this.$element('hobbyDialog').show();},

  // 敞开喜好弹框
  closeHobby() {this.$element('hobbyDialog').close();},

  // 在喜好弹开中点击“确定”confirmHobby() {
    let that = this;
    let copyHobbies = Object.create(Object.getPrototypeOf(this.hobbiesTemp));
    Object.getOwnPropertyNames(this.hobbiesTemp).forEach((items) => {let item = Object.getOwnPropertyDescriptor(that.hobbiesTemp, items);
      Object.defineProperty(copyHobbies, items, item);
    })
    this.hobbies = copyHobbies;
    this.closeHobby();},
  ...
  // 抉择喜好
  checkboxOnChange(event) {
    let currentVal = event.currentTarget.attr.value;
    if (event.checked) {this.hobbiesTemp.push(currentVal);
    } else {
      this.hobbiesTemp = this.hobbiesTemp.filter(item => {return item !== currentVal;});
    }
  },
  ...
}

点击提交按钮对表单进行提交前,先对用户名、明码、电子邮件、喜好进行必填校验,再通过正则表达式对出生日期进行“yyyy-mm-dd”格局校验、对身高进行整数或浮点数校验。// index.jsexport default {…  // 表单提交验证  

// index.js
export default {
  ...
  // 表单提交验证
  buttonClick() {if (this.user === '') {this.showPrompt(this.$t('strings.user_check_null'));
      return;
    }
    if (this.email === '') {this.showPrompt(this.$t('strings.email_check_null'));
      return;
    }
    if (this.hobbies.length === 0) {this.showPrompt(this.$t('strings.hobby_check_null'));
      return;
    }
    if ((this.date !== '') && (!this.checkDateInput(this.date))) {this.showPrompt(this.$t('strings.date_not_format'));
      return;
    }
    if ((this.height !== '') && (!this.checkHeight(this.height))) {this.showPrompt(this.$t('strings.height_not_format'));
      return;
    }
    this.showPrompt(this.$t('strings.success'));
  },
  ...
  // 表单验证后果
  showPrompt(msg) {
    prompt.showToast({
      message: msg,
      duration: CommonConstants.DURATION
    });
  },
  ...
}

总结
您曾经实现了本次 Codelab 的学习,并理解到以下知识点:
1.  input 组件的应用。
2.  label 组件的应用。
3.  dialog 组件的应用。

退出移动版