Search code examples
phplaravelmessagelaravel-validationjsvalidation

How do you display your own error messages with laravel-jsvalidation?


I would like to figure out how to create your own error messages for your rules (e.g. regular expression rules) to be reused by both server PHP and client javascript (using jqueryvalidation through laravel-jsvalidation )

I have tried and can not make it work, and below is a small example to show what I am trying to do but it does not work.

What am I doing wrong?

My small example:

In the file "routes\web.php":

    Route::get('/minimal_example_laravel_jsvalidation', function() {
        // Of course these rules should not really be defined here since 
        // the purpose of the rules is to also reuse them from PHP Laravel code
        // but my problem is now how to generate javascript that can 
        // reuse the same rules and therefore I just put the rules and messages
        // here in this minimalistic example illustrating the problem
        $rules = [
            'three_digits' => 'required|regex:/^\d{3}$/'
        ];    
        $messages = [
            'three_digits' => 'Must be exactly three digits'
        ];
        $validator = JsValidator::make($rules, $messages);
        return view('minimal_example_laravel_jsvalidation')->with("validator", $validator);
    });    

In the file "resources\views\minimal_example_laravel_jsvalidation.blade.php":

...
{!! $validator->selector('#myForm') !!}
...

When using the URL http://localhost:8000/minimal_example_laravel_jsvalidation with the web browser and then "view source" I can see that the following javascript code has been generated by the above "$validator->selector" :

    jQuery(document).ready(function(){

        $("#myForm").each(function() {
            $(this).validate({
                errorElement: 'span',
                errorClass: 'invalid-feedback',

                errorPlacement: function (error, element) {
                    if (element.parent('.input-group').length ||
                        element.prop('type') === 'checkbox' || element.prop('type') === 'radio') {
                        error.insertAfter(element.parent());
                        // else just place the validation message immediately after the input
                    } else {
                        error.insertAfter(element);
                    }
                },
                highlight: function (element) {
                    $(element).closest('.form-control').removeClass('is-valid').addClass('is-invalid'); // add the Bootstrap error class to the control group
                },



                unhighlight: function(element) {
                    $(element).closest('.form-control').removeClass('is-invalid').addClass('is-valid');
                },

                success: function (element) {
                    $(element).closest('.form-control').removeClass('is-invalid').addClass('is-valid'); // remove the Boostrap error class from the control group
                },

                focusInvalid: true,

                rules: {"three_digits":{"laravelValidation":[["Required",[],"The three digits field is required.",true],["Regex",["\/^\\d{3}$\/"],"The three digits format is invalid.",false]]}}            });
        });
    });

Indeed, the error message I get when not writing three digits in the field through my web browser, is as above "The three digits format is invalid." while I expect that it instead should be "Must be exactly three digits" as I defined in the "$messages" array.

I have seen that it is possible with Laravel to create PHP classes with "Custom Validation Rules" where you also can define custom messages, but as far as I understand, if you use those custom rules with laravel-jsvalidation then the validation must be done with AJAX instead of javascript validation directly within the browser, which is what I want to do instead of doing AJAX calls.

I am using these versions:

laravel/framework v7.4.0

proengsoft/laravel-jsvalidation 3.0.0


Solution

  • Try changing messages array like this,

    $messages = [
         'three_digits.required' => 'Three Digits field is required',
         'three_digits.regex' => 'Must be exactly three digits'
    ];
    

    Note I have added rule also to the message key. ('three_digits.required')