kazupon / vue-validator

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

Desync on new input types #309

Open Y-Less opened 7 years ago

Y-Less commented 7 years ago

vue & vue-validator version

1.0.26, 2.0.0

Reproduction Link

<div id="example">
    <validator name="validateColour">
        <label>
            Select:
            <input type="color" v-model="colour" v-validate:colour="['colour']"></input>
        </label>
        <br />
        <label>
            Type (for example purposes only):
            <input type="text" v-model="colour"></input>
        </label>
        <h1 v-show="$validateColour.colour.colour">Invalid colour.</h1>
        <h1 v-else>Good colour.</h1>
    </validator>
</div>

<script type="text/javascript">
Vue.validator('colour', function (data) {
    // Allow a variety of hex formats:
    //   
    //   FFF
    //   #FFF
    //   0xFFF
    //   FFFFFF
    //   #FFFFFF
    //   0xFFFFFF
    //   
    console.log('Passed colour is: ' + data);
    return /^\s*#?(0x|0X)?([0-9a-fA-F]{6}\s*$|[0-9a-fA-F]{3}\s*$)/.test(data);
});

new Vue({
    el: '#example',
    data: {
        colour: 'NOT A COLOUR'
    }
})
</script>

Steps to reproduce

Run the code above. The text box is provided for this example, in a real use of color[sic] input types it obviously wouldn't exist. Every time something is typed in that box, the new value is propagated to the colour input, and the validator is called.

What is Expected?

Invalid colour. should be displayed, since the value of {{colour}} is the string NOT A COLOUR.

What is actually happening?

It seems the validator pulls the string for comparison straight out of the input value, instead of the underlying model. Sadly, it seems that the color input type internally converts all non-colour inputs to 0 (black), so the validator is always called on a valid colour. This is evidenced by the console.log in the colour validator.

The colour button is black regardless of input, unless a real colour in the #HHHHHH format is typed exactly, in which case everything behaves correctly and seems to show that there isn't a mistake in my code (which took a long time to verify).

Moving the v-validate directive to the text input works exactly as expected, as does moving it to a hidden input next to the colour input, for the purposes of display and validation:

        <label>
            Select:
            <input type="color" v-model="colour"></input>
            <input type="hidden" v-model="colour" v-validate:colour="['colour']"></input>
        </label>
kazupon commented 7 years ago

Thank you for your feedback In stable version (2.1.7), input[type="color"] is not supported.

I'll try to support in 3.0.