Vee-validate: Get specific field error for specific rule

Created on 14 Nov 2016  路  9Comments  路  Source: logaretm/vee-validate

I was banging my head around with this. So the thing coming from Angular 1 I used to set a special message for different type of errors in a field. Let's say I have an email input with data-rules="required|email". And if I want to show a message for the email rule I can't just check for that rule in errors.collect('mail').email or errors.collect().email.email. What I got with errors.collect() is an array. And if I want to access a specific rule error I have to check for it by its index that I have to again check in the data-rules attribute. In this case I'd have to check for errors.collect('email')[1] or errors.collect().email[1].

In Angular 1 I can check for the same thing like this form_name.field.$error.rule. so much simpler. If Vue is about simplicity and ease of use then maybe Vee-Validate should follow that rule.

Thank you for the plugin I really like it. But please work on improving it in those areas. And I said something because of my ignorance, please let me know.

All 9 comments

I'm using arrays for the error objects, because of how Vue detects changes, I will try try to improve it as I learn more about how the reactivity works.

Having said that I can add new methods that achieves this behavior. Thanks for the feedback!

Thanks, yes please

Alright thanks! But I made some mistakes above. I mean I was somewhat right in theory. But in practice I seem to have to create a custom validation message for each rule in order to get each message separately because I can't a specific message using errors.collect('email')[0]. I could loop through them, but it would just give the stock messages. So I guess custom validation messages is what I need to set up for now. Can't wait until those features are implemented in the plugin.

And I follow per the documentation but I can't even change the locale to french. I'm using ES6 by the way. When the locale is set to 'en' it works fine, but when it's in 'fr' it says "vee-validate: You are setting the validator locale to a locale that is not defined in the dicitionary. English messages may still be generated.". I don't know whether I'm still going to use that plugin anymore, even though I started to really like it.

I'm sorry about that, probably I missed something about locales, there is a few things you need to consider:

  • If you are importing the locales from the dist directory, then you should include them in the babel transpile process since they are just an ES6 modules. You can download the file individually and integrate it in your project files instead.
  • The locale example in the docs uses a different locale than English, so either I didn't mention something in the docs, or you are setting the locale before merging it into the dictionary.

A code sample will allow me to help you more if I can, and please take into consideration that this plugin is still in beta in order to iron out all these issues. and as always thanks for the feedback!

Hello! I integrate the locales I need in the resources/assets/js folder in the Laravel project I'm working on. So I don't the problem comes from my side. I did use the Validator.updateDictionary() metod the an object containing the new locales. Here's the code I used:

`import messages from './locale/fr';
import Vue from 'vue';
import VeeValidate, { Validator } from 'vee-validate';

Vue.use(VeeValidate);

// Validator.updateDictionary({
// fr: {
// mesages: {
// email: (field) => 'Some English message'
// }
// }
// });

(function( $ ) {
// let $ahSearchForm = $('#ahSearchForm'),
let searchArea = $('#search-area');

$('li.searchAnchor a').on('click', (e) => {
    e.preventDefault();

    searchArea.slideToggle()
});

})(jQuery);

// // Vue Bootstraping

// //
// // methods: {
// // upload: function(e) {
// // e.preventDefault();
// // var files = this.$$.avatar.files;
// // var data = new FormData();
// // // for single file
// // data.append('avatar', files[0]);
// // // Or for multiple files you can also do
// // // _.each(files, function(v, k){
// // // data.append('avatars['+k+']', v);
// // // });

// // this.$http.post('/avatars/upload', data, function (data, status, request) {
// // //handling
// // }).error(function (data, status, request) {
// // //handling
// // });
// // }
// // }

const $http = axios.create({
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-TOKEN': document.querySelector('#token').getAttribute('value')
}
});

Vue.prototype.$http = $http;

// Vue Search
let searchForm = new Vue({
el: '#ahSearchForm',

data: {
    searchTerm: '',
    results: [],
    noResults: false,
    loading: false
},

methods: {
    search () {
        let vm = this;

        if (vm.searchTerm.length > 2) {
            vm.$http.get(ah.searchUrl, {
                params: {q: vm.searchTerm},
            })
            .then(function(response) {
                console.log('object', vm);
                console.log(response);
                let data = response.data.data;

                if (data.length > 0) {
                    vm.loading = true;
                    vm.noResults = false;
                    vm.results = data;
                    vm.loading = false;
                } else {
                    vm.results = [];
                    vm.noResults = true;
                    console.log('no results');
                }
            })
            .catch(function(error) {
                console.log("error: " + error);
            });
        } else {
            this.results = [];
            this.noResults = false;

        }
    }
},

});

let contactForm = new Vue({
el: '#contactForm',

data: {
    sending: false
},

methods: {
    validateBeforeSubmit: function (e) {
        this.$validator.validateAll();

        if (this.errors.any()) {
            e.preventDefault();
        }
    }
},

created () {
    this.$validator.setLocale('fr'); // Switch locale for this instance.
}

});`

So if I'm doing something here let me know. Thanks!

Note that I did uncomment the updateDictionary part. I commented it because it wasn't working properly. And concerning the fix you said would not be difficult to implement, please do it. Because I need this validator in my project. It's kind of weird to get back to Angular for such lack of basic functionalities. I think the Vue community can do better. Especially for beginner-intermediate developers like me. ;)

I'm not sure if this is the issue but I think you had a typo here:

import messages from './fr';
import App from './App.vue';
import Vue from 'vue';
import VeeValidate, { Validator } from 'vee-validate';

Vue.use(VeeValidate);

Validator.updateDictionary({
    fr: {
        messages // you had a typo here 'mesages'
    }
});

and here is a working demo: http://www.webpackbin.com/EkuLkyqZG

Back to the main issue, I have added a new method called firstOf(field, rule, scope?), should be up in the next release.

Good job @logaretm! Thanks for your work. Can't wait for the next release.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Shchepotin picture Shchepotin  路  3Comments

Youdaman picture Youdaman  路  3Comments

schel4ok picture schel4ok  路  3Comments

biapar picture biapar  路  3Comments

MaxMilton picture MaxMilton  路  3Comments