Form dynamic rule validation

The V-decorator directive that comes with the a-Form component makes it easy to validate form items and listen for the change event.

<a-form-item>
  <a-input v-decorator="formItems.username.decorator" />
</a-form-item>
Copy the code
// vue data
this.formItems.username = [
  'username'.  {
    rules: [
 {  required: true. message: 'Please enter a user name'. }, ]. }, ]; Copy the code

However, there may be some forms in the form, one of the two check case. For example, the following form registration example (only one username or email is required)

In this case, you need to remove the mailbox verification after the user enters the user name. Otherwise, the user name verification is removed when the mailbox is entered. At the same time, if both inputs are entered, the corresponding verification logic must be kept.

So how do you do that? Here are the details:

1. How to collect form values?

With the validateFields method, the values object in the internal callback is all the values entered for the current form:

this.form.validateFields((err, values) = > {
  if(! err) {    this.$message.info('Submitted successfully');
  }
});
Copy the code

2. How do I collect specified form items?

This method has been used before, but it has the added detail that you can add the fieldNames array property to the first parameter list of the callback method, using custom to define which fields need to be validated and collected.

Function([fieldNames: string[]], [options: object], callback: Function(errors, values))
Copy the code
this.form.validateFields(this.formFields, (err, values) => {
  / /...
});
Copy the code

3. Finally, how to be dynamic?

That is, modify A, B optional, modify B, A optional.

When creating the form object, set the onValuesChange form value to listen for property events:

this.$form.createForm(this, { onValuesChange: this.onValuesChange });
Copy the code

Update formFields to validateFields in onValuesChange

// Listen for updates to form field values
onValuesChange(props, value, values) {
    const formFields = this.initFormFields();
    // Remove the field verification according to the field logic
    if(values.username && ! values.email) { props.form.resetFields(['email']);  formFields.splice(formFields.indexOf('email'), 1)  } else if(! values.username && values.email) { props.form.resetFields(['username']);  formFields.splice(formFields.indexOf('username'), 1)  }  this.formFields = formFields; } Copy the code

rendering


There was a lot of nonsense, but then I found an easier way

Write the definition of the V-decorator directive alive:

buildDecorator(id, options) {
    const formValues = this.form2.getFieldsValue()
    if (id == 'username') {
    options.rules[0].required = ! formValues.email    }
 if (id == 'email') {  options.rules[0].required = ! formValues.username }  return [id, options] } Copy the code

The directive is triggered to invoke the buildDecorator method every time the data is updated, internally fetching the form values in real time and dynamically modifying the rules to achieve this effect.

In addition, there are several benefits:

  • The code can realize more scenarios (such as form value linkage and adapting to more complex business verification rules combined with related API).
  • The * to the left of the label also becomes dynamic
  • You no longer need to maintain the fieldNames attribute in the validateFields callback method

rendering


The last

Through the latter way, basic can cope with the requirements of complex verification logic, offline you can do more complex object encapsulation to enhance practicality.

Note: the above code is used to illustrate the Demo example, the consideration of the place, please forgive me.

This article is formatted using MDNICE