I'm building a app with Laravel 5.4 and Vue 2.1.10 Now i installed vee-validate 2.0 and everything seems to look fine, like validating except for my locale setting. I want the default EN change to NL (dutch language) but the validating error messages are still default English.
My configuration in my app.js:
import messages from '../../../node_modules/vee-validate/dist/locale/nl';
import Vue from 'vue';
import VeeValidate, { Validator } from 'vee-validate';
// Merge the locales.
Validator.updateDictionary({
nl: {
messages
}
});
const config = {
locale: 'nl',
};
Vue.use(VeeValidate, config);
The script i use on my page
_Really basic, my form is validating but shows the messages in English not in Dutch._
new Vue({
el: '#app',
locale : 'nl'
});
Sorry about that, few things has been changed since beta.24
The built locales actually export an object containing the locale name and the locale object, not the messages as it used to be, so you are going to do the following:
import messages from 'vee-validate/dist/locale/nl';
import Vue from 'vue';
import VeeValidate, { Validator } from 'vee-validate';
import App from './App.vue';
// Merge the locales.
Validator.addLocale(messages);
const config = {
locale: 'nl'
};
Vue.use(VeeValidate, config);
new Vue({
el: '#app',
render: h => h(App)
})
I will update the docs, thanks for the feedback
This setup works great on v: 2.0.0-beta.25!
Thanks @logaretm
import Vue from "vue";
import VeeValidate from "vee-validate";
import VeeValidateMessagesBR from "vee-validate/dist/locale/pt_BR";
VeeValidate.Validator.addLocale(VeeValidateMessagesBR);
Vue.use(VeeValidate, {locale: 'pt_BR'});
add this way to document, otherwise it will make others feel unsure about that.
@Loliner already been added
http://vee-validate.logaretm.com/localization.html#localized-files
@logaretm but that example is rather confusing, if you aren't adding the Vue.use() part, then you should consider kamihouse's approach instead.
For me, after trying everything, only this worked:
import Vue from "vue";
import VeeValidate from "vee-validate";
import validationLocaleCs from "src/lang/cs.validation";
VeeValidate.Validator.addLocale(validationLocaleCs);
Vue.use(VeeValidate, {locale: 'cs'});
VeeValidate.Validator.setLocale('cs');
notice the call to setLocale. Without that, the messages would stay in English.
@Arxi, can you please tell, what is inside your src/lang/cs.validation file? Is it just JSON?
it is a .js file which looks like this (it's not fully translated yet, I tested it with required and email messages):
// @todo: translate!
const messages = {
_default : (field) => `The ${field} value is not valid.`,
after : (field, [target]) => `The ${field} must be after ${target}.`,
alpha_dash : (field) => `The ${field} may contain alpha-numeric characters as well as dashes and underscores.`,
alpha_num : (field) => `The ${field} may only contain alpha-numeric characters.`,
alpha_spaces : (field) => `The ${field} may only contain alphabetic characters as well as spaces.`,
alpha : (field) => `The ${field} may only contain alphabetic characters.`,
before : (field, [target]) => `The ${field} must be before ${target}.`,
between : (field, [min, max]) => `The ${field} must be between ${min} and ${max}.`,
confirmed : (field) => `The ${field} confirmation does not match.`,
credit_card : (field) => `The ${field} is invalid.`,
date_between : (field, [min, max]) => `The ${field} must be between ${min} and ${max}.`,
date_format : (field, [format]) => `The ${field} must be in the format ${format}.`,
decimal : (field, [decimals] = ['*']) => `The ${field} must be numeric and may contain ${decimals === '*' ? '' : decimals} decimal points.`,
digits : (field, [length]) => `The ${field} must be numeric and exactly contain ${length} digits.`,
dimensions : (field, [width, height]) => `The ${field} must be ${width} pixels by ${height} pixels.`,
email : (field) => `Pole ${field} mus铆 b媒t platnou emailovou adresou.`,
ext : (field) => `The ${field} must be a valid file.`,
image : (field) => `The ${field} must be an image.`,
in : (field) => `The ${field} must be a valid value.`,
ip : (field) => `The ${field} must be a valid ip address.`,
max : (field, [length]) => `The ${field} may not be greater than ${length} characters.`,
max_value : (field, [max]) => `The ${field} must be ${max} or less.`,
mimes : (field) => `The ${field} must have a valid file type.`,
min : (field, [length]) => `The ${field} must be at least ${length} characters.`,
min_value : (field, [min]) => `The ${field} must be ${min} or more.`,
not_in : (field) => `The ${field} must be a valid value.`,
numeric : (field) => `The ${field} may only contain numeric characters.`,
regex : (field) => `The ${field} format is invalid.`,
required : (field) => `Pole ${field} je povinn茅.`,
size : (field, [size]) => `The ${field} must be less than ${size} KB.`,
url : (field) => `The ${field} is not a valid URL.`
};
const attributes = {
email : "Email",
password : "Heslo",
old_password : "Sou膷asn茅 heslo",
new_password : "Nov茅 heslo",
name : "Jm茅no"
};
const locale = {
name : 'cs',
messages,
attributes
};
export default locale;
@Arxi, I see, thanx. It's looks like that messages fields must be functions. And couldn't be static JSON. Am I right, @logaretm?
For example, something like that doesn't work for me:
{
"messages": {
"required": "This field is required.",
"email": "This field must be a valid email.",
"confirmed": "The field confirmation does not match.",
"ext": "This field must be a valid file.",
"mimes": "This field must have a valid file type."
},
"attributes": {
"name": "Name",
"email": "Email",
"password": "Password",
"password_confirm": "Confirm password"
}
}
attributes is detecting well, but messages returns error.
@romandragan Yep, messages are functions that return strings, I can add support later for strings but functions provides a greater deal of flexibility although when needed.
@logaretm, yeah, I agree that functions provide a great experience. But in my architecture I need to lazily fetch translation data on language changing event, and not to bundle all locales data to the build.js because our app have a lot of supported languages, which might increase bundle size.
Maybe you can advise some workaround how to handle this in vee-validate?
You can use webpack's async modules using import() should split your app files and import them when needed, I can't think of another way atm.
@logaretm, thank you for the advise! I've already come to this too. I just import() my JSON language file and then process it's content to generate attributes and messages:
import { Validator } from 'vee-validate';
return System.import('~assets/i18n/' + locale + '.json').then((data) => {
const validationDictionary = {};
validationDictionary[locale] = {
attributes: data.validation.attributes,
messages: {},
};
for (const rule in data.validation.messages) {
if (data.validation.messages.hasOwnProperty(rule)) {
validationDictionary[locale].messages[rule] = (field) => {
// This could be extended to support dynamic message, that uses "field" variable
return data.validation.messages[rule];
};
}
}
Validator.updateDictionary(validationDictionary);
Validator.setLocale(locale);
});
Note, that this will only work in webpack v.2
It works for me on version ^2.1.0-beta.6
import VeeValidate, { Validator } from 'vee-validate'
import vi from 'vee-validate/dist/locale/vi'
Validator.localize({ vi: vi })
Vue.use(VeeValidate, {locale: 'vi'})
For those who are still struggling with this in vee-validate ^3.4.5 and Vue ^2.6.11, here is my solution:
import Vue from 'vue'
import {
ValidationProvider,
ValidationObserver,
localize,
extend
} from 'vee-validate'
import * as rules from 'vee-validate/dist/rules'
import es from 'vee-validate/dist/locale/es.json'
for (const rule in rules) {
extend(rule, rules[rule])
}
localize('es', es)
Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
If someone has a better solution for looping through the rules and adding them I'll be glad to know that.
Most helpful comment
It works for me on version
^2.1.0-beta.6