kazupon / vue-validator

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

v-bind:class="$validation1.mywords.valid ? 'has-success' : 'has-error'" do not work! #120

Closed hldgaofeng closed 8 years ago

hldgaofeng commented 8 years ago
why this do not work: <input v-bind:class="$validation1.mywords.valid ? 'has-success' : 'has-error'" />
this work fine:  <input v-bind:someprop="$validation1.mywords.valid ? 'has-success' : 'has-error'" />
this work fine: <input class="some class {{$validation1.mywords.valid ? 'has-success' : 'has-error'}}" />
kazupon commented 8 years ago

Thank you for your feedback! :smile_cat:

I checked your code. https://jsfiddle.net/kazupon/zqs5xgmn/1/

the above code, I think that there is no problem.

Can you provide the code to us ?

hldgaofeng commented 8 years ago
<!-- demo root element -->
<div id="demo3">
    <validator name="validation1">
    <form id="search" novalidate>
        <!-- BUG? 在 v-bind:class 中无法使用下面的表达式 -->
        <div class="form-group "
            v-bind:class="$validation1.mywords.valid ? 'has-success' : 'has-error'"
            >
            <label class="control-label">关键字</label> <input name="query" 
            class="form-control"
            v-validate:mywords="{ maxlength: 2, required:true }"
            v-model="searchQuery">
        </div>
    </form>
    <div class="alert alert-danger" v-show="!$validation1.mywords.valid">
        <span v-show="$validation1.mywords.required">关键字必须填写!</span>
        <span v-show="$validation1.mywords.maxlength">关键字最大长度为 2 个字符!</span>
    </div>
    <pre> {{ $validation1 | json }} </pre>
    </validator>
    <table-ctl
        test-prop="asdf"
    :data="gridData"
    :columns="gridColumns"
    :filter-key="searchQuery">
    </table-ctl>
</div>

Uncaught TypeError: Cannot read property 'valid' of undefined(anonymous function) @ VM1470:3Watcher.get @ vue.js:3112Watcher @ vue.js:3080Directive._bind @ vue.js:7716linkAndCapture @ vue.js:6404compositeLinkFn @ vue.js:6382Fragment @ vue.js:4409FragmentFactory.create @ vue.js:4611insert @ vue.js:4653insert @ vue-validator.js:764render @ vue-validator.js:759(anonymous function) @ vue-validator.js:748(anonymous function) @ vue.js:216_dir.vm.(anonymous function) @ vue-validator.js:598bind @ vue-validator.js:753Directive._bind @ vue.js:7696linkAndCapture @ vue.js:6404compositeLinkFn @ vue.js:6382Vue._compile @ vue.js:7980Vue.$mount @ vue.js:8945Vue._init @ vue.js:2408Override.Vue._init @ vue-validator.js:317Vue @ vue.js:9004(anonymous function) @ test_ctl.html:249h.execCb @ require.js:30Z.check @ require.js:18(anonymous function) @ require.js:23(anonymous function) @ require.js:8(anonymous function) @ require.js:24v @ require.js:7Z.emit @ require.js:24Z.check @ require.js:19(anonymous function) @ require.js:23(anonymous function) @ require.js:8(anonymous function) @ require.js:24v @ require.js:7Z.emit @ require.js:24Z.check @ require.js:19(anonymous function) @ require.js:23(anonymous function) @ require.js:8(anonymous function) @ require.js:24v @ require.js:7Z.emit @ require.js:24Z.check @ require.js:19Z.enable @ require.js:23Z.init @ require.js:17E @ require.js:14h.completeLoad @ require.js:28h.onScriptLoad @ require.js:30

hldgaofeng commented 8 years ago
<!DOCTYPE html>
<html>

<head>
    <script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript" src="vue-validator.js"></script>
</head>

<body>
    <div id="demo3">
        <validator name="validation1">
            <form id="search" novalidate>
                <!-- BUG? v-bind:class can not access $validation1.mywords  ? -->
                <div class="form-group " v-bind:xxx="$validation1.mywords.valid ? 'has-success' : 'has-error'"
                        v-bind:class="{'asdf':$validation1.mywords.valid}">
                    <label class="control-label">Please Enter:</label>
                    <input class="form-control" v-validate:mywords="{ maxlength: 2, required:true }"  />
                </div>
            </form>
            <div class="alert alert-danger" v-show="!$validation1.mywords.valid">
                <span v-show="$validation1.mywords.required">must not empty!</span>
                <span v-show="$validation1.mywords.maxlength">maxlength = 2!</span>
            </div>
            <pre> {{ $validation1 | json }} </pre>
        </validator>
    </div>
    <script language="javascript">
        Vue.config.debug = true;
        var vm = new Vue({
            el: '#demo3',
            data: {
            }
        })
    </script>
</body>

</html>

Download the Vue Devtools for a better development experience: https://github.com/vuejs/vue-devtools vue.js:974 [Vue warn]: Error when evaluating expression "{'asdf':$validation1.mywords.valid}". vue.js:978 Uncaught TypeError: Cannot read property 'valid' of undefined(anonymous function) @ VM197:3Watcher.get @ vue.js:3112Watcher @ vue.js:3080Directive._bind @ vue.js:7716linkAndCapture @ vue.js:6404compositeLinkFn @ vue.js:6382Fragment @ vue.js:4409FragmentFactory.create @ vue.js:4611insert @ vue.js:4653insert @ vue-validator.js:1211render @ vue-validator.js:1206(anonymous function) @ vue-validator.js:1195(anonymous function) @ vue.js:216_dir.vm.(anonymous function) @ vue-validator.js:1027bind @ vue-validator.js:1200Directive._bind @ vue.js:7696linkAndCapture @ vue.js:6404compositeLinkFn @ vue.js:6382Vue._compile @ vue.js:7980Vue.$mount @ vue.js:8945Vue._init @ vue.js:2408Override.Vue._init @ vue-validator.js:365Vue @ vue.js:9004(anonymous function) @ index.html:29

kazupon commented 8 years ago

Thank you for your reporting!!

I guess that this issue related #35 #103 #111 This issue occur the error when you are using development build of vue.js. This issue does not occur the error in the standalone minified build of vue.js.

we can avoid this issue by setting the Vue.config.warnExpressionErrors = false.

hldgaofeng commented 8 years ago

Thanks a lot for your response!

simonj commented 8 years ago

But if you set Vue.config.warnExpressionErrors = false it will not show warnings on other things, right? Is it not just a "hack"?

zbartl commented 8 years ago

I'm still having this issue, specifically when used in the following:

<input type="text" class="form-control" placeholder="address" v-model="addr" v-validate:addr="['required']" v-bind:class="$validation.addr.valid ? 'validation_success' : 'validation_failed'" />

If not binding on the same element as the validate, I don't see this happen.

tapaheh commented 8 years ago

I confirm, the issue still persists

<input type="text"
  v-model="surname_user"
  v-validate:surname_user="['required']"
  v-bind:class="$validation.surname_user.valid ? '' : 'error'"
>

triggers vue.common.js?e881:987 [Vue warn]: Error when evaluating expression "$validation.surname_user.valid ? '' : 'error'": TypeError: Cannot read property 'valid' of undefined (found in component: <app>)

Is there any way this can be fixed without having to set Vue.config.warnExpressionErrors = false?

kazupon commented 8 years ago

This warning error is difficult to avoid perfectly in vue-validator. This warning error is occuring to access the validation property that not initialize. This warning error is difficult to avoid perfectly.

We can avoid to use computed property. example:

computed: {
  userValid: function () {
    return this.$validation.user && this.$validation.user.valid ? '' : 'error'
  }
}