Search code examples
jqueryvue.jsvalidationvuelidate

Validate a 'required' field using a dynamic validation schema


The project_id is required to be validated on form submit:

<td>
    <select2 
        name="project_id" 
        id="project_id"
        v-model.trim="item.project_id.$model"
        v-bind:class="{
            'is-invalid': item.project_id.$error,
            'is-valid':
            item.project_id.$dirty &&
            !item.project_id.$error,
        }"
    >
        <option value="">Select</option>
        <option v-for="(project) in projects" 
            :selected="project.id == timesheet.project_id" 
            :key="project.id" 
            :value="project.id"
        >{{ project.name }}
        </option>
    </select2>
</td>
<td><input type= "checkbox" name="disable" v-on:click="disabled()"></td>
<script>
    import { required, minLength } from "vuelidate/lib/validators";
    validations() {
        return{
            timesheet: {
                items: {
                    required,
                    minLength: minLength(1),
                    project_id: { required },
                }
            }
        }
    },
    disabled(){
        $('#project_id').attr('disabled', true);
    }
</script>

How to make the field non-required when the disable checkbox is checked? I tried with the requiredIf validator, but seems like am missing somewhere:

            $each: {
                project_id: { 
                    required: requiredIf (function(item){
                        return this.disable
                    })
                },
            },

Solution

  • You probably trying to do the following in your disable() function:

    document.getElementById("project_id").removeAttribute("required");
    // or
    document.getElementById("project_id").setAttribute("required", "");
    

    To decide if you need to remove the attribute you need to apply a v-model property to your <input type= "checkbox" name="disable" v-on:click="disabled()">. If a this checkbox is checked, it´s property would turn true, else it would be false.


    EDIT: Here is a complete example of usage.

    <template>
      <div>
        <select id="project_id" required>
          <option value="bar">Option 1</option>
          <option value="foo">Option 2</option>
          <option value="baz">Option 3</option>
        </select>
        <input type="checkbox" name="disable" v-model="clickedBox" @change="checkSelected">
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          clickedBox: false
        }
      },
      methods: {
        checkSelected() {
          if (this.clickedBox === true) {
            document.getElementById("project_id").removeAttribute("required");
          }
          else {
            document.getElementById("project_id").setAttribute("required", "");
          }
        }
      }
    }
    </script>
    

    If the checkbox is checked project_id will loose it´s required attribute. If it´s unchecked, the required attribute would be set again.


    EDIT2: Using dynamic validation schema

    If you want to use a dynamic validation schema for project_id, you need to use it like this:

    validations() {
      if (!this.clickedBox) {
        return {
          timesheet: {
            items: {
              required,
              minLength: minLength(1),
              project_id: { required },
            }
          }
        }
      } else {
        return {
          timesheet: {
            items: {
              required,
              minLength: minLength(1),
              project_id: ''
            }
          }
        }
      }
    }
    

    See the documentation for further information: Dynamic validation schema