ParsleyJS - Localization with data-parsley-`constraint`-message

bzmw picture bzmw · Aug 22, 2014 · Viewed 9.9k times · Source

Currently I'm using

data-parsley-`constraint`-message="English sentence goes here"

but now that I'm working to add localization these messages will never be translated using the i18n library because they are custom.

Is there a way to add something like

data-parsley-`constraint`-message-fr="Francais francais francais"

or someway to do it through JS?

Specifically I'm using data-parsley-required-message=""

Answer

Luís Cruz picture Luís Cruz · Aug 23, 2014

Why don't you use the localization of Parsley instead of defining the messages on the inputs?

I suggest you download the localizations that you need from the source. After that, according to the docs you can load the i18n before the plugin, like this:

<script src="i18n/fr.js"></script>
<script src="i18n/it.js"></script>
<script src="parsley.min.js"></script>
<script type="text/javascript">
    window.ParsleyValidator.setLocale('fr');
</script>

Or you can load the i18n after the plugin (in that case, it will assume the last loaded localization - in the following example it will be Italian), like this:

<script src="parsley.min.js"></script>
<script src="i18n/fr.js"></script>
<script src="i18n/it.js"></script>

On my projects I typically load the needed localization based a Cookie or Session variable:

<script src="parsley.min.js"></script>
<script src="i18n/"<?= echo $lang ?>".js"></script>

With either of the options, you don't need to add data-parsley-constraint-message to each input. And when you need to change a message you can do that in the localization file.

To conclude, if you need custom validators, you can check the docs to see how you can define the different localizations.


UPDATE

This solves the OP's need by changing the source code of the plugin

You can edit in your parsley.js a method called _getErrorMessage (line 1264 with 2.0.4), which looks like this:

_getErrorMessage: function (fieldInstance, constraint) {
    var customConstraintErrorMessage = constraint.name + 'Message';
    if ('undefined' !== typeof fieldInstance.options[customConstraintErrorMessage])
        return window.ParsleyValidator.formatMessage(fieldInstance.options[customConstraintErrorMessage], constraint.requirements);
    return window.ParsleyValidator.getErrorMessage(constraint);
},

To something like this:

_getErrorMessage: function (fieldInstance, constraint) {
    //added
    var locale = window.ParsleyValidator.locale;
    var namespace = fieldInstance.options.namespace;
    var customConstraintErrorMessage = namespace  + constraint.name + '-' + locale;

    if (fieldInstance.$element.attr(customConstraintErrorMessage)) {
        // treat parameters
        if (fieldInstance.$element.attr(customConstraintErrorMessage).indexOf("%s") !== -1)
            return window.ParsleyValidator.formatMessage(fieldInstance.$element.attr(customConstraintErrorMessage), constraint.requirements);
        return fieldInstance.$element.attr(customConstraintErrorMessage);
    }

    // original
    var customConstraintErrorMessage = constraint.name + 'Message';
    if ('undefined' !== typeof fieldInstance.options[customConstraintErrorMessage])
        return window.ParsleyValidator.formatMessage(fieldInstance.options[customConstraintErrorMessage], constraint.requirements);
    return window.ParsleyValidator.getErrorMessage(constraint);
},

With this, you can specify the messages directly in the input, using the sintax data-parsley-constraint-locale. Here is a sample:

<input type="text" name="name" value="" data-parsley-required="true"
    data-parsley-required-en="Name is required"
    data-parsley-required-pt="O nome é obrigatório" />
<input type="number" name="phone" value=""
    data-parsley-minlength="9"
    data-parsley-minlength-en="Phone length must be equal to %s"
    data-parsley-minlength-pt="O telefone deverá ter %s digitos" />

When you need to use some kind of constrains (in the above example, there is data-parsley-minlength which is variable) you can use the %s inside the message. This will be replaced for the correct value.

Just before you bind parsley to your form, you need to set the locale you want to use (beware: you need to include the javascript file relative to the locale that you are using, otherwise you will get an error like Error: pt is not available in the catalog):

window.ParsleyValidator.setLocale('pt');
$("#myForm").parsley();

Here is a jsfiddle for demonstration. If you want to test, just setLocale('en') and see the messages in English.