vue.jsvalidationvuejs2element-uielement-plus

How to enable/disable submit button based on form validation state in Element UI?


Using element-ui, the form validation is pretty decent, so I was expecting it to be pretty straight-forward to "wire up" a variable that represents whether the form is valid to the "submit" button.

I can certainly write a validation function and attach it to appropriate events on every field, but that seems duplicative.

For example, each rule already has a trigger that tells it when to evaluate the rule (e.g. blur, change). If I have to attach an event to each el-input that mirrors the same triggers, that feels fragile to me.

For example, these rules trigger on blur or change.

    rules: {
        username: [
            {
                required: true,
                message: "please enter user name",
                trigger: "blur"
            },
            {
                min: 3,
                max: 32,
                message: "length must be 3 to 32 characters",
                trigger: "blur"
            }
        ],
        password: [
            {
                required: true,
                message: "please enter password",
                trigger: "change"
            }
        ]
    }

Am I missing something? Is there a way to do this, uh, elegantly?


Solution

  • Here's what I ended up doing:

    I used the vue.js 'watch' facility to monitor the form data (the key being that 'deep' is set so it monitors the field values) and run a check on it, updating a variable that disables the submit button:

    The data section contains my form model and the enable variable:

    data() {
        return {
            loginForm: {
                username: "",
                password: ""
            },
            formValid: false,
            ...
    

    Which is attached to the button:

    <el-button @click="submit" type="primary" :disabled="!formValid">Log In</el-button>
    

    And the validation code, which is very generic (and may be able to be moved to a plugin):

    watch: {
      loginForm: {
        handler(){
          this.checkForm();
        },
        deep: true
      }
    },
    methods: {
        checkForm() {
            let fields = this.$refs.loginForm.fields;
            if (fields.find((f) => f.validateState === 'validating')) {
                setTimeout(() => {
                    this.checkForm();
                }, 100);
            }
            this.$data.formValid = fields.every(f => {
                let valid = f.required && f.validateState === "success";
                let notErroring = !f.required && f.validateState !== "error";
                return valid || notErroring;
            }, true);
            console.log('valid:', this.$data.formValid);
        },
        ...
    

    (got this last part from another very useful post. It craftily handles the possibility of in-flight validation)