3

I am trying to make a field required if feature is enabled(if you select checkbox). But that validation is not triggering by click on select/unselect checkbox

 <b-form-checkbox v-model="form.banner.enabled">
     <span class="label-title control-label">Enable</span>
 </b-form-checkbox>

Vue js

validations: {
    form: {
        banner:{
            image:{
                required: requiredIf(function() {
                    console.log("Image validator called")
                    return this.form.banner.enabled;
                })
            }
        }
    },
  },

I unselect checkbox, Still Image field gives an error that Its required

<b-form-input id="bannerImage" name="bannerImage" v-model="form.banner.image" :state="$v.form.banner.image.$dirty ? !$v.form.banner.image.$error : null"></b-form-input>
<b-form-invalid-feedback >
     <span >The image field is required.</span>
</b-form-invalid-feedback>

You can replicate - Remove the value of image and uncheck enabled option and click save. It will give an error The image field is required. because validator is not calling on submit. Code for submit is

this.$v.form.$touch()
if (this.$v.form.$anyError) {
     return; //return if any error
}
//execute save form code if no error

Refer Image enter image description here

3 Answers3

6

I will add to BRose response that I wouldn't use such deep level object in the data, even if it's supposed to work as we expect.

To the validations as a function I don't think it's necessary. You can keep it as an object, only try to set the required as a function. As you can see here, other people found requiredIf to not work as we expect it too. I was trying to do the same as you are: use requiredIf to check for a value and set the property as required or not. After not using requiredIf and assigning a function to required I started checking the property $v inside the component I believe I understood how it behaves.

Initially I though that the following code would be sufficient:

validations: {
    form: {
        banner:{
            image:{
                required: function() {
                    return this.form.banner.enabled;
                },
            },
        },
    },
}

I was wrong! This does not work as I expected because the property required in the $v.form.banner.image is a boolean that reflects if the input condition is met and my function is incomplete. So it cannot only check if it should be required, it must check if the required condition is met, which is the following code, assuming this data structure:

data() {
  return {
    form: {
      banner: {
        enabled: true,
        image: '',
      }
    }
  }
},
validations: {
    form: {
        banner:{
            image:{
                required: function() {
                    return this.form.banner.enabled ? !!this.form.banner.image : true;
                },
            },
        },
    },
}

This will check if the content is required and if exists, and if is not required it will return true, because the requirement is met.

After struggling a little I came to this conclusion without using requiredIf, since I needed a more customised validation.

el.mano.el
  • 544
  • 5
  • 7
1

try turning validations into a function

validations() {
    const validations = {
       form: {
         banner:{
           image:{}
         }
       }
    };

    if (this.enabled) {
      validations.form.banner.image = {
        required
      };
    }

    return validations;
  }

change "this.enabled" with your specified trigger

BRose
  • 227
  • 2
  • 12
0

what does form look like in your data object?

based on your v-model form.banner.image you are going several levels deep (which vue doesn't like unless you are using something like cloneDeep). furthermore it would be better to tie the checkbox input into something you can keep track of in the state.

something like:

data() {
    return {
      imageEnabled: false,
    };
  }

then try the above code and replace 'this.enabled' with 'this.imageEnabled' and have it v-modeled to the input checkbox

BRose
  • 227
  • 2
  • 12
  • My data object - return { form: { banner:{ enabled:true, image:null, }, }, } – Meenakshi Khandelwal Nov 25 '19 at 21:34
  • And it worked when i use and validation is required: requiredIf(function() { return this.$v.form.banner.enabled == "enabled"; }) how mulitlevel works when checkbox does not have boolean value but not with boolean value – Meenakshi Khandelwal Nov 25 '19 at 21:39
  • Based on what you're showing me, the only thing we would really change from my code is: if (this.form.banner.enabled) { validations.form.banner.image = { required }; } essentially we are telling vuelidate only make this element required when enabled is true. If you are working on chrome, I highly suggest you download vue devtools if you haven't already, and check your state to make sure enabled is properly triggering and your data looks like it should. Best of luck! – BRose Nov 25 '19 at 21:41