Hello Universe
Hello Universe

Reputation: 3302

How to validate text input fields receiving dates such that it is between 4 and 8 weeks from today?

I have several input fields. And, I am validating these fields using jQuery Validation Plugin as can be found from here: https://jqueryvalidation.org/

I can validate input text fields and input text fields receiving date values. However, I need to ensure the date received is between 4 and 8 weeks from today. How to do that?

HTML:

<form>
    Name: <input type="text" maxlength="50" class="nf-givenname"><br/> <br/> 
    date that does not work: 

    <input type="text" maxlength="45" class="nf-date-picker" name="Date">
    <br/> <br/> 

    <input type="submit" value="Submit" class="btn-save date"  commandtype="Save">
</form>

And, the jQuery code is as below for me so far:

$(document).ready(function() {
    var $form = $("form");
    $form.validate({
        submitHandler: function() {
            //
        }
    });

    // Ensures the classNames associated with the form elements can be used for validation
    $.validator.addClassRules = function(className, rules) {
        if (className.constructor === String) {
            var obj = {};
            obj[className] = rules;
            className = obj;
        }

        $.each(className, function(n, r) {
            $("." + n).each(function(i, e) {
                var self = $(e);
                self.rules("add", r);
            });
        });
    };

    $.validator.addMethod(
        "dateRange",
        function(value, element, params) {
            console.log("value is" + value);
            try {
                console.log(
                    "Entered value is" +
                        value +
                        " params.from  is" +
                        params.from +
                        " param to is" +
                        params.to
                );
                if (value > params.from && value < params.to) {
                    return true;
                }
            } catch (e) {}
            return false;
        },
        "Please enter date within range (4 to 8 weeks)"
    );

    var formattedDate = new Date()
            .toJSON()
            .slice(0, 10)
            .split("-")
            .reverse()
            .join("-"),
        dateTokens = formattedDate.split("-"),
        dt = new Date(dateTokens[2], parseInt(dateTokens[1], 10) - 1, dateTokens[0]), // months are 0 based, so need to add 1
        inFourWeeks = new Date(dt.getTime() + 28 * 24 * 60 * 60 * 1000)
            .toJSON()
            .slice(0, 10)
            .split("-")
            .reverse()
            .join("-"),
        inEightWeeks = new Date(dt.getTime() + 56 * 24 * 60 * 60 * 1000)
            .toJSON()
            .slice(0, 10)
            .split("-")
            .reverse()
            .join("-");

    var fromDate = inFourWeeks;
    var toDate = inEightWeeks;

    $(".nf-date-picker").addClass("myDateFieldRangeValidate");

    $.validator.addClassRules({
                myDateFieldRangeValidate: {
            dateRange: {
                from: fromDate,
                to: toDate
            }
        },

        "nf-givenname": {
            required: true,
            messages: {
                required: "Please specify your given (first) name"
            }
        },

        "nf-date-picker": {
            required: true,
            messages: {
                required: "Please choose a date"
            }
        }
    });
});

I created a pen to show what I am struggling with at the moment. Link of the codepen of the work is as follows: https://codepen.io/hellouniverse/pen/aGjoKw?editors=1012

Upvotes: 1

Views: 182

Answers (1)

hallleron
hallleron

Reputation: 1992

The problem is the messages property, which doesn't seem to be fully supported by addClassRules() method. I don't know if this is a viable alternative for you, but I saved your rules object to var rules and loop over it to set the class name as the name attribute. This way you can add the rules the default way. Is this an option for you?

EDIT: I added a custom validation method for the default date check. It validates if the entered date is between your range of 4 to 8 weeks. The date format is set to dd/mm/yyyy. This should get you going ...

var $form = $("form");
  
var rules = {
    "nf-givenname": {
		    required: true,
        messages: {
            required: "Please specify your given (first) name"
	      }
		},
		"nf-date-picker": {
			  required: true,
			  date: true
        //dateISO: true
		},
		"txt_dob": {
		    required: true
		}
};
  
$form.validate({
    submitHandler: function(form) {
        //
		}
});


// Date format is dd/mm/yyyy for the validation!
$.validator.methods.date = function(value, element) {
    var dates = {
        "today": new Date(),
        "four_weeks": new Date(new Date().getTime() + (1000 * 60 * 60 * 24 * 28)),
        "eight_weeks": new Date(new Date().getTime() + (1000 * 60 * 60 * 24 * 56))
    };
    
    
    for (var k in dates) {
        if (dates.hasOwnProperty(k)) {
            var dd = dates[k].getDate();
            var mm = dates[k].getMonth()+1;
            
            if (dd < 10) dd = '0' + dd;
            if (mm < 10) mm = '0' + mm;
           
            dates[k] = dd + '/' + mm + '/' + dates[k].getFullYear();
        }
    }

    var date_from = dates["four_weeks"].split("/");
    var date_to = dates["eight_weeks"].split("/");
    var val =  value.split("/");

    var from = new Date(
        date_from[2],
        parseInt(date_from[1])-1, date_from[0]
    );
    
    var to = new Date(
        date_to[2],
        parseInt(date_to[1])-1, date_to[0]
    );
    
    var check = new Date(
        val[2],
        parseInt(val[1])-1, val[0]
    );

    return this.optional(element) || (check > from && check < to);
}
  
//------ Only for this test to prevent snippet reload.
$form.on('submit', function(e){
    e.preventDefault();
});
//------ 
  
  
for (var k in rules) {
    if (rules.hasOwnProperty(k)) {
        $('.' + k).attr('name', k).rules('add', rules[k]);
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/additional-methods.min.js"></script>

<form>
	Name: 
  <input type="text" maxlength="50" class="nf-givenname">
  <br/> <br/> 
	date that does not work:
	<input type="text" maxlength="45" class="nf-date-picker hasDatepicker">
	<br/> <br/> 
	date that does  work: 
	<input type="text" class="txt_dob" name="loreumipsum" />
	
	<input type="submit" value="Submit" class="btn-save date"  commandtype="Save">
</form>

Upvotes: 1

Related Questions