Link to home
Start Free TrialLog in
Avatar of needxpert
needxpert

asked on

PHP Date Validation for Form

My form requires Date of Birth entered in three selects as MM/DD/YYYY and there are two different age limits, depending on the type of user entered.  Both are currently being validated through javascript and returning immediate errors however users can still submit with invalid dates.

I believe that I need for the dates to be validated and required by my PHP program in order to stop invalid form submissions.  I'm looking for the script to accomplish that validation advice on the best way.

Here is the current javascript validation for the date of birth fields:

 On my form, I have three select fields representing MM, DD, YYYY that are currently being tested for maximum age.  I also need to check that the dates selected are valid, as it relates to # of days in month and leap years.  Looking for a script that will work well with existing check and validate date prior to age check.

Here is current script:  

<SCRIPT LANGUAGE="JAVASCRIPT">
 
<!-- hide this script tag's contents from old browsers
 
function checkAge(mode)
 
{
 var max_age =75; //Considering its the parent
/* set the maximum age you want to allow in */
 if(mode=="member" || mode=="member2") {
 max_age=75;
 }
 
 if(mode=="child" || mode=="child2" || mode=="child3" || mode=="child4" || mode=="child5") {
max_age=23;
 }
 
 
/* change "age_form" to whatever your form has for a name="..." */
 
var year = parseInt(document.forms["signup"]["year" + mode].value);
 
var month = parseInt(document.forms["signup"]["month" + mode].value)-1;
 
var day = parseInt(document.forms["signup"]["day" + mode].value);
 
var theirDate = new Date((year + max_age), month, day);
 
var today = new Date;
 
var birth = new Date(year, month, day);
 
var age = today.getFullYear() - birth.getFullYear();
 
if (theirDate < today) {
 
alert("Member must be under " + max_age + " years of age.");
 
return false;
 
}
 
else {
 
return true;
 
}
 
}
 
// -- done hiding from old browsers -->
 
</script>
Avatar of pmessana
pmessana

If you are validating with Javascript I am not sure how they are still able to submit.  If you place the call to your validation in the "onSubmit" and return "false" if they fail then the form will never submit and you can use the client side to validate versus using the server to validate.  This is more user friendly IMHO since the user doesn't submit the form at all and they are notified of their errors immediately.  

If you want to do server side you can get more fancy with the error when it is returned and highlight is more easily, etc.  But from the soudns of it you just need to move it to the onSubmit and you would be good to go.  

If this doesn't answer your question, post you code out here so I can take a look and understand better what you are doing and why you want it to be done on the server.
Avatar of needxpert

ASKER

Is it possible to validate the fields on change and onsubmit?  The client would like the immediate error message to appear, which is why I had it checking on change after the year entry.  I would prefer the method you described - just need some guidance.


Yes, you can do it in the actual field when it is changed, as I assume you are now and you can also do it on submit in the following context.  Anytime it is returned 'false' the form will not submit.

<form.........onSubmit="return checkAge()"............
For other validation that exists, the form includes an onsubmit="return validateStandard(this)"

Can I add to that and it will still function? Would the code help?  It's a multi-page form that's been creatively distributed to several tabbed panels [due to original software limitations] and we're making it jump through some hoops...
I believe you can pass both at once with a semi colon between them.  However, I have always used a submit handler function that I call from the form, that function then makes the calls out to the other other functions and controls the error messages back, thus I have one call off the form and then handle the errors as I need, this means you can return multiple errors at once.

Example:
onSubmit="return validateAll()"

function validateAll() {
   validateAgeReturn=validateAge();
   validateFoodReturn=validateFood();
   validateEtcReturn=validateEtc();

   if (validateAgeReturn) {
        alert('Age is wrong');
        exit();
   }

}

That should get you going if you know javascript.  I am certainly not a javascript expert and if my syntax is wrong in there it is only because I am typing it on the fly but I believe it should work and you can handle the errors as you wish, you could even bring them all together and do one alert.
Unfortunately, my javascript is limited - I've tried several variations to what you posted but nothing seems to be working for me - the form does not return another error on submit and allows form submission.  I really appreciate your direction and believe it's the right way to handle this, I just can't seem to capture the right context with the various validations that exist.


sorry for the delay :]

<SCRIPT LANGUAGE="JAVASCRIPT">
 
<!-- hide this script tag's contents from old browsers
 var dtCh= "/";
var minYear=1900;
var maxYear=2100;
 
function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}
 
function stripCharsInBag(s, bag){
	var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}
 
function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   } 
   return this
}
 
function isDate(dtStr){
	var daysInMonth = DaysArray(12)
	var pos1=dtStr.indexOf(dtCh)
	var pos2=dtStr.indexOf(dtCh,pos1+1)
	var strMonth=dtStr.substring(0,pos1)
	var strDay=dtStr.substring(pos1+1,pos2)
	var strYear=dtStr.substring(pos2+1)
	strYr=strYear
	if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
	if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
	for (var i = 1; i <= 3; i++) {
		if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12){
		alert("Please enter a valid month")
		return false
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		alert("Please enter a valid day")
		return false
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
		return false
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		alert("Please enter a valid date")
		return false
	}
return true
}
function checkAge(mode)
 
{
 var max_age =75; //Considering its the parent
/* set the maximum age you want to allow in */
 if(mode=="member" || mode=="member2") {
 max_age=75;
 }
 
 if(mode=="child" || mode=="child2" || mode=="child3" || mode=="child4" || mode=="child5") {
max_age=23;
 }
 
 
/* change "age_form" to whatever your form has for a name="..." */
 
var year = parseInt(document.forms["signup"]["year" + mode].value);
 
var month = parseInt(document.forms["signup"]["month" + mode].value)-1;
 
var day = parseInt(document.forms["signup"]["day" + mode].value);
 if(isDate(month + '/' + day + '/' + year)==false) {
return false;
}
var theirDate = new Date((year + max_age), month, day);
 
var today = new Date;
 
var birth = new Date(year, month, day);
 
var age = today.getFullYear() - birth.getFullYear();
 
if (theirDate < today) {
 
alert("Member must be under " + max_age + " years of age.");
 
return false;
 
}
 
else {
 
return true;
 
}
 
}
 
// -- done hiding from old browsers -->
 
</script>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of pmessana
pmessana

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your suggested code - I'm actually having  both problems:

The date fields all seem to return the correct error message on onChange but nothing I seem to include in the form validation actually stops the form from submitting - even with the invalid dates.

Is there another way I should tackle all of the form validation - perhaps the order of things over time is working against me.


SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think I'm confused, since all of my date of birth fields contain three select variables, none of which are named age (or any variation of). Can you provide a more obvious example of the solution I should try - sorry...beginner on javascript context..