kazupon / vue-validator

:white_check_mark: Validator component for Vue.js
MIT License
2.19k stars 431 forks source link

Property values need to modified twice to trigger validation checks for values modified with watch after vue 1.0.22 #241

Open aaronjpitts opened 8 years ago

aaronjpitts commented 8 years ago

Hi,

I've noticed a bug which happens using Vue 1.0.22 and up. If you have a validator checking a field which can have it's value modified by a watch, the validator doesn't detect a change to the input until you modify a field value twice. For example I have a price field, we store our prices in cents, so we need to multiple the value the user inputs by 100 (using watch). The validator doesn't detect a change to the field until the user makes two changes to the input field, i.e. if they type a single number such as '9' the validator doesn't detect a change and therefore still fails validation, but if you then either change the number or add a second number to make it '91' for example, the validator detects a user input and applies the validation.

I use your validator like this to make it work with my field component (which handles many field types).


    <validator name="setupPropertyBillsValidation">
      <form>

              <field :property.sync="property.data.internetMonthlyPrice" :field-data="fields.internetMonthlyPrice" :currency="property.data.currency"></field>
              <input type="hidden" v-model="property.data.internetMonthlyPrice" v-validate:internet-monthly-price="fields.internetMonthlyPrice.validation">

      </form>
    </validator>

My field component then uses this inputPrice.vue field component to handle price fields:

<template>
  <div class="input-addon">
    <span class="input-addon__prefix">{{ currencySymbol(currency) }}</span>
    <input type="number" v-model="price" :min="fieldData.min" :max="fieldData.max" :name="fieldData.ID" class="input input-addon__field-with-prefix" :placeholder="fieldData.placeholder">
  </div>

</template>

<script type="text/babel">
  import currencySymbol from '../mixins/currencySymbol.js'

  export default {
    mixins: [
      currencySymbol
    ],

    props: {
      currency: {
        required: true
      },
      fieldData: {
        required: true
      },
      property: {
        required: true,
        twoWay: true
      }
    },

    data () {
      return {
        price: null
      }
    },

    ready () {
      // If price already saved, divide it by 100 to output the real value in the input field
      if(this.property !== null) {
        this.price = this.property / 100;
      } else if (this.property === 0) {
        this.price = 0;
      }
    },

    watch: {
      'property' (newVal) {
        if(newVal !== null) {
          this.price = this.property / 100;
        } else if (newVal === 0) {
          this.price = 0;
        }
      },
      'price' (newVal) {
        if (newVal || newVal === 0) { // If valid price inputted multiply it into cents
          this.property = this.price * 100;
        } else if (newVal === 0) { // Leave 0 if price is 0 (free)
          this.property = 0;
        } else { // Set back to null if price input is cleared
          this.property = null;
        }
      }
    }
  }
</script>

As said, before updating to vue 1.0.22 or higher this worked fine, but now any property which has its value modified by a watch, needs to be modified twice before the validator detects a change to the value and checks its validation.

Thank you to look into this, Aaron

aaronjpitts commented 8 years ago

If it helps, the problem may be between this commit https://github.com/vuejs/vue/commit/a821faf2948d20746197c239200b614072cfca6a and vue 1.0.22 as we have been using the development version of vue 1.0.21 with this commit and it was still working up until this commit at least.

kazupon commented 8 years ago

Thank you for your feedback! Can you provide the minimum reproduction code with jsfiddle (or jsbin, codepen...) please?

kazupon commented 8 years ago

In-activity

szkrd commented 8 years ago

I'm pretty new to Vue, but I think this watch-update bug happens here: https://jsfiddle.net/szabi/v0jm4xgy/

A manual focus and blur fixes the value, but not the value change in the watcher.

aaronjpitts commented 8 years ago

Any update on this? We cannot provide a repo but with the reop by szkrd and our example above it should be clear enough to reproduce this issue.

Thank you

wuyiw commented 8 years ago

https://jsfiddle.net/v0jm4xgy/1/ with initial="off", is it the right behavior that first tap changes 'modified' state and second tap changes 'valid' state ?

aaronjpitts commented 7 years ago

Any update?