Jelajahi Sumber

Form: add invalidFields as a second param of validation callback (#10279)

杨奕 7 tahun lalu
induk
melakukan
cf7f117bfb

+ 2 - 2
examples/docs/en-US/form.md

@@ -849,8 +849,8 @@ All components in a Form inherit their `size` attribute from that Form. Similarl
 
 | Method | Description | Parameters |
 | ---- | ---- | ---- |
-| validate | the method to validate the whole form. Returns a promise if callback is omitted | Function(callback: Function(boolean)) |
-| validateField | the method to validate a certain form item | Function(prop: string, callback: Function(errorMessage: string)) |
+| validate | validate the whole form. Takes a callback as a param. After validation, the callback will be executed with two params: a boolean indicating if the validation has passed, and an object containing all fields that fail the validation. Returns a promise if callback is omitted | Function(callback: Function(boolean, object)) |
+| validateField | validate a certain form item | Function(prop: string, callback: Function(errorMessage: string)) |
 | resetFields | reset all the fields and remove validation result | — |
 | clearValidate | clear validation message for all fields | -
 

+ 1 - 1
examples/docs/es/form.md

@@ -854,7 +854,7 @@ Todos los componentes de un formulario heredan su atributo `size`. De manera sim
 
 | Metodo        | Descripción                              | Parametros                               |
 | ------------- | ---------------------------------------- | ---------------------------------------- |
-| validate      | el método para validar todo el formulario. Devuelve una promesa si se omite el return | Function(callback: Function(boolean))    |
+| validate      | el método para validar todo el formulario. Takes a callback as a param. After validation, the callback will be executed with two params: a boolean indicating if the validation has passed, and an object containing all fields that fail the validation. Devuelve una promesa si se omite el return | Function(callback: Function(boolean, object))    |
 | validateField | el método para validar un determinado form item | Function(prop: string, callback: Function(errorMessage: string)) |
 | resetFields   | restablece todos los campos y elimina el resultado de validación | —                                        |
 | clearValidate | limpia mensaje de validación para todos los campos | -

+ 1 - 1
examples/docs/zh-CN/form.md

@@ -837,7 +837,7 @@ W3C 标准中有如下[规定](https://www.w3.org/MarkUp/html-spec/html-spec_8.h
 
 | 方法名      | 说明          | 参数
 |---------- |-------------- | --------------
-| validate | 对整个表单进行校验的方法。若不传入回调函数,则会返回一个 promise | Function(callback: Function(boolean))
+| validate | 对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promise | Function(callback: Function(boolean, object))
 | validateField | 对部分表单字段进行校验的方法 | Function(prop: string, callback: Function(errorMessage: string))
 | resetFields | 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 | -
 | clearValidate | 移除整个表单的校验结果 | -

+ 2 - 2
packages/form/src/form-item.vue

@@ -192,11 +192,11 @@
 
         model[this.prop] = this.fieldValue;
 
-        validator.validate(model, { firstFields: true }, (errors, fields) => {
+        validator.validate(model, { firstFields: true }, (errors, invalidFields) => {
           this.validateState = !errors ? 'success' : 'error';
           this.validateMessage = errors ? errors[0].message : '';
 
-          callback(this.validateMessage);
+          callback(this.validateMessage, invalidFields);
         });
       },
       clearValidate() {

+ 8 - 4
packages/form/src/form.vue

@@ -7,6 +7,8 @@
   </form>
 </template>
 <script>
+  import objectAssign from 'element-ui/src/utils/merge';
+
   export default {
     name: 'ElForm',
 
@@ -104,13 +106,15 @@
         if (this.fields.length === 0 && callback) {
           callback(true);
         }
-        this.fields.forEach((field, index) => {
-          field.validate('', errors => {
-            if (errors) {
+        let invalidFields = {};
+        this.fields.forEach(field => {
+          field.validate('', (message, field) => {
+            if (message) {
               valid = false;
             }
+            invalidFields = objectAssign({}, invalidFields, field);
             if (typeof callback === 'function' && ++count === this.fields.length) {
-              callback(valid);
+              callback(valid, invalidFields);
             }
           });
         });

+ 34 - 0
test/unit/specs/form.spec.js

@@ -686,6 +686,40 @@ describe('Form', () => {
         });
       });
     });
+    it('invalid fields', done => {
+      var checkName = (rule, value, callback) => {
+        if (value.length < 5) {
+          callback(new Error('长度至少为5'));
+        } else {
+          callback();
+        }
+      };
+      vm = createVue({
+        template: `
+          <el-form :model="form" :rules="rules" ref="form">
+            <el-form-item label="活动名称" prop="name" ref="field">
+              <el-input v-model="form.name"></el-input>
+            </el-form-item>
+          </el-form>
+        `,
+        data() {
+          return {
+            form: {
+              name: ''
+            },
+            rules: {
+              name: [
+                { validator: checkName, trigger: 'change' }
+              ]
+            }
+          };
+        }
+      }, true);
+      vm.$refs.form.validate((valid, invalidFields) => {
+        expect(invalidFields.name.length).to.equal(1);
+        done();
+      });
+    });
     it('validate return promise', done => {
       var checkName = (rule, value, callback) => {
         if (value.length < 5) {

+ 2 - 1
types/form.d.ts

@@ -7,8 +7,9 @@ export interface ValidateCallback {
    * The callback to tell the validation result
    *
    * @param isValid Whether the form is valid
+   * @param invalidFields fields that fail validation
    */
-  (isValid: boolean): void
+  (isValid: boolean, invalidFields: object): void
 }
 
 export interface ValidateFieldCallback {