JQuery Validate for 3 field date

A difficult and challenging task I had been given is to use the JQuery validate.js to validate the date fields, but this was then split out into 3 fields. One for day, month and of course year, which sounds easy, but it was not. The issue comes that validate.js is built to validate one field on its own and we wanted to validate not just each field, but also as a whole date.

I researched the web and most developers suggested amending the JavaScript library file. However the version we had was minified and of course we had other teams using that copy, so using this method would affect others code. I thought about putting the validation for the whole date in with each of the fields, but this then produced the same validation each message for the whole date 3 times because it was doing it for each of the fields. There was a suggestion from developer to use a group method, but I couldn’t seem to get that working.

So I persisted to make my own method. This may not be the best, but I found it worked well and passed testing so it can’t be that bad. You can read more about the library of JQuery Validate here and learn the basics, which will make this all seem a bit easier.

First we need to validate each field on their own for example make sure the month is between 1 and 12. Instead of making a validation made for each field I made a universal method that all of them could use.

In the example below you can see in the ‘params’ parameter I passed in a array that has the minimal number and the maximum number. You would pass for example of month [1,12]. This is then validated on exit to check the ‘value’ of the field, stored in ‘dateValue’, is between or equal to the range.

 

     $.validator.addMethod("vailddatefield",

        function (value, element, params) {

            var dateValue = parseInt(value, 10);

            var Min = parseInt(params[0], 10);

            var Max = parseInt(params[1], 10);

           return this.optional(element) || (dateValue >= Min && dateValue <= Max );

        },

        "Please enter a valid age"

    );

 

You can then attach this to the field like so:

//Month validation

        $(".month").rules("add", {

            vailddatefield: [1,12],

            messages: {

                vailddatefield:  'Please enter a month value between 1 and 12'

            }

        });

 

The issue then comes when you want to validate these all together. If you was to enter the validation for the whole date in the method above then when an error happened it would produce the message once for each field with the same text. This then means we need a single field to evaluate if the full date is valid and then validate against that.

If you add the below snippet into the previous method, you can then pass the class or IDs for each of the date fields. These can then be concatenated together to make a full date, then put into a hidden field. This now holds our full date string in good format ready for validating.

 

            //validate full date

            var day = $(params[2]);

            var month = $(params[3]);

            var year = $(params[4]);

            var fullDate= $(params[5]);

 

            $(fullDate).val($(day).val() + '/' + month.val() + '/' + year.val());

 

This however still doesn’t solve how we are going to validate it. To fire the validation by the library as normal, you need to give focus to the field then leave it, which is impossible because it is hidden. So we use some magic… If you put the below statement in, it forces the JavaScript to validate that field. This then runs its attached validation from the library. If you enter this into the previous method as well, so no matter which fields they start or finish in, it will validate the full date in the end. You will also only get only one message to appear if the field is invalid.

$(fullDate).valid()

Something I also did was stop it validating until all the fields are complete, as you don’t want to say their date is invalid before they even get chance to fill it out, so I changed the above to be the below. This then checks that each field has it minimal length of value before it validates the whole date.

if ((dayBirth.val().length >= 1) && (monthBirth.val().length >= 1) && (yearBirth.val().length > 3)) {

                $(fullBirth).valid()          

 }

 

You can now see the whole code for the validation method. This will validate each field on its own, while also validating the whole date. You will need to add your own method for validating the full date, but if you read up on the library this should be easy.

/// Check Valid date

    $.validator.addMethod("vailddatefield",

        function (value, element, params) {

            var dateValue = parseInt(value, 10);

//Get max and min dates

            var Min = parseInt(params[0], 10);

            var Max= parseInt(params[1], 10);

 

 //validate full date

            var day = $(params[2]);

            var month = $(params[3]);

            var year = $(params[4]);

            var fullDate= $(params[5]);

 

//enter full date

            $(fullDate).val($(day).val() + '/' + month.val() + '/' + year.val());

 

//Validate full date

if ((dayBirth.val().length >= 1) && (monthBirth.val().length >= 1) && (yearBirth.val().length > 3)) {

                $(fullBirth).valid()          

 }

           return this.optional(element) || (dateValue >= Min && dateValue <= Max);

        },

        "Please enter a valid age"

    );

 

Below here you can then see the example of calling the new methods for Month and for the full date. You can always also add more validation methods.

 

//Month required

        $(".validate-month").rules("add", {

            vailddatefield: [1,12,'.day','.month','.year','.fulldate'],

            messages: {

                vailddatefield:  'Please enter a month between 1 and 12'

            }

        });

 

//full date

        $(".validate-date").rules("add", {

            vailddate: '',

            messages: {

                vailddate:  'Please enter valid date'

            }

        });

Any thoughts and other methods people have seen can be shared in the comments section below.

Advertisements

Leave a message please

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s