element form 动态循环出来的元素进行校验

2020-12-05  本文已影响0人  bypwan

亲,先看效果

image.png

简单说明

材料相关的是通过增加数组的长度属性动态创建出来的,并且校验材料名称。运单数量。签收数量必填
追重要的是需求校验签收数量不能大于运单数量

知识点

1,el-form的动态增减表单项:
循环动态建的元素属性名的书写遵循:

<el-form-item
    v-for="(domain, index) in dynamicValidateForm.domains"
    :label="'域名' + index"
    :key="domain.key"
    :prop="'domains.' + index + '.value'"
    :rules="{
      required: true, message: '域名不能为空', trigger: 'blur'
    }"
  >
    <el-input v-model="domain.value"></el-input><el-button @click.prevent="removeDomain(domain)">删除</el-button>
  </el-form-item>

上面是重点
2,统一对象之间的输入内容关联校验
如:输入签收数量,或运单数量校验签收数量
用到el-form的methods 对部分表单字段进行校验的方法 validateField
例如:

this.$refs['defaultData'].validateField('signMaterials.' + index + '.signinQuantity')

defaultData为表单的ref ,signMaterials为变化的材料数组,index为操作的数组的当前项,signinQuantity为校验的属性

代码实现

html

 <el-form
      :model="formData"
      :rules="rules"
      ref="defaultData"
      label-width="100px"
      class="application-signForm"
    >
     
      <el-card style="margin-bottom: 18px;">
        <el-row
          class="material-item"
          v-for="(material, index) in formData.signMaterials"
          :ref="'signMaterials.' + index"
          :key="index"
        >
          <el-col :span="11">
            <el-form-item
              label="材料名称"
              label-width="110px"
              :prop="'signMaterials.' + index + '.materialId'"
              :required="required"
              :rules="{
                validator: validateMaterial,
                trigger: ['change', 'blur'],
              }"
            >
              <frequent-material-select
                ref="materialSelect"
                :width="195"
                @material-change="materialChange"
                :row-data="material"
                :index="index"
                :select-options="selectOptions"
                :hidelabel="true"
              ></frequent-material-select>
            </el-form-item>
          </el-col>
          <el-col>
            <el-col :span="12">
              <el-form-item
                label="运单数量"
                label-width="110px"
                label-position="left"
                :required="required"
                :prop="'signMaterials.' + index + '.deliveryQuantity'"
                :rules="{
                  validator: validateDeliveryQuantity,
                  trigger: ['change', 'blur'],
              }"
              >
                <el-input
                  class="deliveryQuantity-class"
                  @input.native="deliveryQuantityChange($event, material, index)"
                  v-model="material.deliveryQuantity"
                ></el-input>
              </el-form-item>
            </el-col>
// 设置prop属性必须这样子才能起到校验的效果
            <el-col :span="12">
              <el-form-item
                label="签收数量"
                label-width="110px"
                label-position="left"
                :required="required"
                :prop="'signMaterials.' + index + '.signinQuantity'"
                :rules="{
                  validator: validateSignQuantity,
                  trigger: ['change', 'blur'],
              }"
              >
                <el-input
                  @input.native="signQuantityChange($event, material, index)"
                  @blur="signQuantityBlur($event,material)"
                  class="signinQuantity-class"
                  v-model="material.signinQuantity"
                ></el-input>
              </el-form-item>
            </el-col>
          </el-col>
          <el-col :span="22" v-if="material.showReadOnly">
            <el-col :span="5" class="seat">
              <label class="el-form-item__label">
                累计签收量:
              </label>
            </el-col>
            <el-col :span="7">
              <span class="application-spanstyle">
                {{ material.cumulativeSignShow }}{{ material.unit }}
              </span>
            </el-col>

            <el-col :span="5" class="seat">
              <label class="el-form-item__label">
                {{ material.controlName }}:
              </label>
            </el-col>
            <el-col :span="7">
              <span class="application-spanstyle">
                {{ material.controlQuantity }}{{ material.unit }}
              </span>
            </el-col>
          </el-col>
          <el-col :span="2" :offset="22" class="btn-delete" v-if="formData.signMaterials.length>1">
            <el-tooltip
              class="item"
              effect="dark"
              content="删除本条材料"
              placement="bottom"
            >
              <i
                class="el-icon-circle-close icon-delete"
                @click="deleteMaterial(index)"
              />
            </el-tooltip>
          </el-col>
        </el-row>
        <div class="add-btn">
          <span @click="addMaterial">
            + 添加材料
          </span>
        </div>
      </el-card>
      </el-row>
    </el-form>

js

methods:{
// 1,增加数组长度,增加材料按钮
  addMaterial(){
        this.formData.signMaterials.push(JSON.parse(JSON.stringify(this.materialItem)))
      },
//2,删除材料
deleteMaterial(index){
        this.formData.signMaterials.splice(index,1)
      },
//3,校验材料名称必填且材料不能重复
       validateMaterial(rule, value, callback) {
        if (!value) {
            callback(new Error('请输入材料名称'));
        }
        let flag = 0
        this.formData.signMaterials.forEach(item => {
          if (item.materialId === value) {
            flag++
          }
        })
        if (flag >= 2) {
          callback(new Error('材料不能重复'))
          return false
        }else{
           callback();
        }
       },
//4,校验运单数量:运单数量不能超过3位小数
      validateDeliveryQuantity(rule, value, callback){
            var pattern = /^0$|^[1-9]\d{0,15}$|^[1-9]\d{0,15}\.{1}\d{1,3}$|^0\.{1}\d{1,3}$/g;
            //alert(pattern.test(value));

            if (value == null || value === '') {
                callback(new Error('请输入运单量'));
                return false;
            } else if (value < 0 || value > 100000) {
                //校验数字在0-100000之间,最多3位小数
                callback(new Error('请输入0-10万之间数字'));
                return false;
            }
            else if(!pattern.test(value)){
                callback(new Error('最多输入3位小数'));
                return false;
          }
            callback();
        },
//5,校验签收数量:签收数量不能超过3位小数
        validateSignQuantity(rule, value,callback){
            const deliveryQuantity = this.formData.signMaterials &&this.formData.signMaterials[this.currentIndex] && this.formData.signMaterials[this.currentIndex].deliveryQuantity
            var pattern = /^0$|^[1-9]\d{0,15}$|^[1-9]\d{0,15}\.{1}\d{1,3}$|^0\.{1}\d{1,3}$/g;
            //alert(pattern.test(value));
            if (value == null || value === '') {
                callback(new Error('请输入签收量'));
                return false;
            } else if (value < 0 || value > 100000) {
                //校验数字在0-100000之间,最多3位小数
                callback(new Error('请输入0-10万之间数字'));
                return false;
            }else if(!pattern.test(value)){
                callback(new Error('最多输入3位小数'));
                return false;
            }
            else if(parseFloat(value) > parseFloat(deliveryQuantity) ){
              callback(new Error('签收数量不能大于运单数量的数据'))
            }
            callback();
        },
// 5.输入运单数量手动触发校验签收数量(*本文的重点,卡了好久,主要还是对element的对部分字段校验不熟悉)
       deliveryQuantityChange($event,material,index){
         if(material.signinQuantity){
           this.currentIndex = index
           this.$refs['defaultData'].validateField('signMaterials.' + index + '.signinQuantity')
         }
        },
}
上一篇下一篇

猜你喜欢

热点阅读