q-input model changed even if validation fails



  • Hi everyone,

    On my page I use a q-input to collect a value from the user. The changed value triggers the execution of a method:

        <q-input
          filled
          v-model="model"
          label="Maximum 3 characters"
          :rules="[ val => val.length <= 3 || 'Please use maximum 3 characters']"
        />
    

    During typing, the value of ‘model’ is used to fetch data from server by calling doAction:

        model: {
          get () {
             ...
          },
          set (value) {
             this.doAction(value)
         }
      }
    

    The problem is that the doAction method is called even if the value is invalid. The setter is called before the validation takes place.
    And this confuses me. In case of a validation error, I expected that the model value wouldn’t change, because this is the intention of validation - to only set valid values.

    So, do I miss something? How can I be sure that only valid values are set - or how can I ensure that doAction is only called if the validation doesn’t fail?

    Thanks for your help.
    Best regards
    Daniel



  • @daniel
    This is the expected behavior. How can you validate a model if it is not changed before 😉

    Your problem, if I understand it well, is that you call the action on each input event (remember, v-model is equivalent to :value=... and @input=...). If this is really your intention, then, you have to check for valid input inside your doAction() method.

    Add a ref to you input, and then :

    doAction() {
      this.$refs.inputref.validate()
      if (this.$refs.inputref.hasError) {
        return
      }
      // ... Do action here
    }
    

    Also, instead of doing a getter/setter for your model, you can just use a data property, and add a @input event to your q-input.
    You can also use debounce property to avoid unnecessary server call while typing.



  • @tof06 Thank you so much for your help.

    So, I changed it as you suggested. But: now I have a new problem. hasError is always false. I changed my template to:

    <q-input
       filled
       v-model="model"
       @input="(value) => setModelValue(value)"
       label="Maximum 3 characters"
       debounce="1500"
       ref="modelRef"
       :rules="[ val => val.length <= 3 || 'Please use maximum 3 characters']"
    >
    

    Model is now a data property:

    data () {
        return {
          model: "0",
        }
      }
    

    and the setModelValue method looks like this:

    setModelValue (value) {
      let isValid = this.$refs.modelRef.validate()
      // or: this.$refs.modelRef.hasError
      if (!isValid) {
        return
      }
      ...
    }
    

    If I enter an invalid value, isValid is true and this.$refs.modelRef.hasError is false. But the error message on the input field is shown, which means, the input is invalid. If I enter an other invalid value, isValid is now false. In case of a correct value, isValid is still false. Only if I enter an other valid value, isValid is true. It seems, that the validation state is one validation behind.

    So, I do not unterstand why calling validate() returns true (which means, no validation error), but the correct error message is shown? What have I done wrong?

    Best regards,
    Daniel



  • @tof06 I tried your suggestion, but without luck. Please see my post above. Thanks again.



  • I try to make a codepen : https://codepen.io/cp-tof06/pen/mdVyayN?editors=1011

    Add the value parameter in your @input handler. Looks like the handler is called before updating model 😉



  • @tof06 Thank you so much. Now, it’s working!


Log in to reply