Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent form validation errors to be removed from the DOM with Parsleyjs

I am validating a password field with parsleyjs. The password has three requirements and thus three validation messages:

  • Password needs to have at least 8 characters
  • One special character is required
  • One number is required

When a validation returns successful I do not want the message to be removed but to stay in place and visually style the message, in this case with a green checkmark ( default the message has a red error icon). So basically want to add a class or remove and keep the message in the DOM.

As an example when one integer has been inserted the validation might look like this:

enter image description here

Is it possible with parsley to prevent the default behavior (removing the message) and add a successful class to a corresponding error message (not just the error list container)?

Here is what I have so far and a codepen demo

$(function() {
    $('.form').parsley();
});

window.Parsley.addValidator('number', {
    validateString: (value) => {
        const format = /\d/;
        return format.test(value);
    },
    messages: {
        en: 'One number is required'
    }
});

window.Parsley.addValidator('specialChar', {
    validateString: (value) => {
        const format = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/;
        return format.test(value);
    },
    messages: {
        en: 'One special character is required'
    }
});
like image 630
Ingvi Jónasson Avatar asked Feb 20 '17 12:02

Ingvi Jónasson


1 Answers

I came up with this solution for your problem which works fine.

You can test it on this Codepen Link.

HTML

<form class="form">
    <label for="password-01">Password:</label>
  <input class="password" id="password-01" type="password" required 
data-parsley-class-handler=".errors"
data-parsley-errors-container=".errors"
data-parsley-special-char="" data-parsley-number="" minlength="8" data-parsley-validation-threshold="0" data-parsley-trigger="keyup" data-parsley-priority-enabled="false"/>
    <input type="submit" value="Submit" />
</form>
<div class="feedback">
    <div class="success"></div>
    <div class="errors"></div>
</div>

CSS

body {
    font-family: sans-serif;
}

.form {
    padding: 1rem;
    background: lightgrey;
}

label {
    display: block;
    margin-bottom: .2rem;
}

.feedback {
    margin-top: 1rem;
    border: 1px solid gray;
    padding: 2rem;
}

.parsley-errors-list {
    list-style: none;
    padding-left: 0;
    margin: 0;
}

.parsley-errors-list li {
    color: red;
}

.success {
    color: green;
}

Javascript

$(function() {
    $('.form').parsley();   

    window.Parsley.addValidator('number', {
        validateString: (value) => {
            const format = /\d/;
            return format.test(value);
        },
        messages: {
            en: 'No number'
        }
    });

    window.Parsley.addValidator('specialChar', {
        validateString: (value) => {
            const format = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/;
            return format.test(value);
        },
        messages: {
            en: 'No special character'
        }
    });

    $('.password').on('keyup', function() {

        $('.success').html(""); // clear success div

            // check numbers success
            if (window.Parsley._validatorRegistry.validators.number.validateString($('.password').val())){      
                $('.success').append( window.Parsley._validatorRegistry.validators.number.messages.en +"<br>");
            }


            // check specialChar success
            if (window.Parsley._validatorRegistry.validators.specialChar.validateString($('.password').val())){     
                $('.success').append( window.Parsley._validatorRegistry.validators.specialChar.messages.en +"<br>");
            }

        var length = $('.password').val().length;

            // check if input is empty
            if (length > 0){
                    $('.success').append("This value is required.<br>");
            }

            // check minlength success  
            var minlength = $('.password').attr("minlength");
            if (length >= minlength){
                $('.success').append("This value is too short. It should have "+minlength+" characters or more.<br>");
            }



    });

});

Changes in HTML:

What I did is that I added a div for the green messages (success div), a div for the red messages (errors div) and rearranged the feedback div to this:

<div class="feedback">
    <div class="success"></div>
    <div class="errors"></div>
</div>

Also in the input attributes I replaced this:

data-parsley-class-handler=".feedback"
data-parsley-errors-container=".feedback"

with this:

data-parsley-class-handler=".errors"
data-parsley-errors-container=".errors"

Changes in CSS:

I renamed this CSS part: .parsley-errors-list .success to this: .success.

Changes in Javascript:

In the javascript I added the function window.Parsley.on('field:validate', function() {...}); which is triggered before the check of the validators (see here under Events List). In there I added 4 if statements which check if the numbers validator is correct, if the specialChar validator is correct, if the input is not empty and if the length of the input is bigger or equal to the minlength. If any of these are true then the corresponding message is added to the div success which has the color green for the text. Before adding these, the success div is cleared ($('.success').html("");) in order for the green messages to be updated.


Hope this was helpful. Please let me know if there is something you didn't understand or you wanted it differently.

Sources:

  • http://api.jquery.com/append/
  • http://api.jquery.com/attr/
  • http://api.jquery.com/val/

UPDATE

Since you want to make the messages stay in the same position, you can check this Codepen I created. I deleted the errors and success divs from the html, and added the function below in the javascript:

$('.password').on('input', function() {

    $('.feedback').html(""); // clear feedback div

    // check numbers success
    if (window.Parsley._validatorRegistry.validators.number.validateString($('.password').val())){      
        $('.feedback').append("<font color='green'>" + window.Parsley._validatorRegistry.validators.number.messages.en +"</font><br>");
    } else {      
        $('.feedback').append("<font color='red'>" + window.Parsley._validatorRegistry.validators.number.messages.en +"</font><br>");
    }   

    // check specialChar success
    if (window.Parsley._validatorRegistry.validators.specialChar.validateString($('.password').val())){     
        $('.feedback').append("<font color='green'>"+ window.Parsley._validatorRegistry.validators.specialChar.messages.en +"</font><br>");
    } else {
        $('.feedback').append("<font color='red'>"+ window.Parsley._validatorRegistry.validators.specialChar.messages.en +"</font><br>");
    }

    var length = $('.password').val().length;

    // check if input is empty
    if (length > 0){
        $('.feedback').append("<font color='green'>This value is required.</font><br>");
    } else {
        $('.feedback').append("<font color='red'>This value is required.</font><br>");
    }

    // check minlength success  
    var minlength = $('.password').attr("minlength");
    if (length >= minlength){
        $('.feedback').append("<font color='green'>This value is too short. It should have "+minlength+" characters or more.</font><br>");
    } else {
        $('.feedback').append("<font color='red'>This value is too short. It should have "+minlength+" characters or more.</font><br>");
    }   

});

With the function above, every time the input is changed, the feedback div is cleared and then the 4 conditions are checked and the messages are added in the feedback div colored green if the corresponding condition is true or colored red otherwise.

like image 66
Thanasis1101 Avatar answered Oct 21 '22 22:10

Thanasis1101