0

I have a set of predefined rules which is loaded with a rest call from an external resource.

rules.yaml

rules:
  firstname:
    rule: value.length <= params.max
    message: Bitte geben Sie nicht mehr als {{params.max}} Zeichen ein
    params:
      max: 20
  lastname:
    rule: value.length <= params.max
    message: Bitte geben Sie nicht mehr als {{params.max}} Zeichen ein
    params:
      max: 30

Then i wrote a custom validator like this:

window.Parsley.addValidator('rules', {
    rules: rules,
    validateString: function (value, requirement) {
        let constraint = rules[requirement];
        if (constraint) {
            let params = constraint.params;
            if (constraint.message) {
                let errorMessage = Mustache.render(constraint.message, {params: params, value: value});
            }
            return !value || eval(constraint.rule);
        } else {
            console.log('Invalid constraint: $requirement could not be found inside $rules');
            return false;
        }
    },
    requirementType: 'string',
    messages: {
        en: 'The string ist invalid %s.',
        fr: 'Ce nombre n\'est pas un multiple de %s.'
    }
});

Validation works as expected. But as you can see, the error message is dynamically computed during validation. How can Parsley use my computed message in this setup?

Guido Zockoll
  • 141
  • 3
  • 11

2 Answers2

1

Instead of true or false, you can return a failed promise with the argument being the error message.

return $.Deferred().reject('Custom error message')
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
  • The rules definition file contains many more business rules and some are more complex than these simple ones. The rules file is shared between multiple projects. We even share these rules between frontend and backend so i need something as a rule interpreter. – Guido Zockoll Dec 09 '16 at 05:37
  • Best write independent custom validators. With your "meta" custom validator, you are not actually sharing any logic. – Marc-André Lafortune Dec 09 '16 at 13:24
0

If someone cares about a different solution here is how I would do it.

In case of a validation error, add a message (messages in case of multiple languages) manually inside the "validateString" method.

window.Parsley.addValidator('myCustomValidator', {
    validateString: function (value, requirement) {
        let isValid = false;
        // define dynamic messages
        window.Parsley.addMessage('de', 'myCustomValidator', 'Das ist ein Fehler');
        window.Parsley.addMessage('en', 'myCustomValidator', 'This is an error');

        if (isValid == true) {
            return true;
        } else {
            return false;
        }
    },
    requirementType: 'string',
    messages: {
        // leave blank since the messages get defined dynamically inside parseString method
    }
});
Artur Cichosz
  • 1,034
  • 7
  • 18