m-hrt,
Try this. It validates name, card number and date fields so it's a bit more than you asked for. From this you should be able to see how client-side form validation works. The main parts of the trick are to attach the validate() function as the form's onsubmit handler and to return true to allow submission, or false to suppress it.
As you will see, I have chosen to give colour coded feedback to the user rather than an alert, but I am sure you wil be able to work out where to insert an alert if you want one.
You will also see that a form is more neatly formatted with a table rather than using to pad it out.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Untitled</title>
<style type="text/css">
#cardDetails td { vertical-align:top; }
#cardDetails td p { margin:0; font-size:9pt; }
</style>
<script language="JavaScript" type="text/javascript">
var $ = Object.prototype.$ = function(id) { return (document.getElementById) ? document.getElementById(id): document.all[id]; };
function validate(form) {
var resultCodes = [];//Will be populated with -ve numbers for errors, +ve for validated
var allNumeric = /^[0-9]+$/;
//Name validation
if($('fname').value === '') { resultCodes.push(-1); }//check 1: error
else { resultCodes.push(1); }//check 1: pass
//Card number validation
var el_1 = $('card_number_field1');
var el_2 = $('card_number_field2');
var el_3 = $('card_number_field3');
var el_4 = $('card_number_field4');
if(!el_1 || !el_1.value || !allNumeric.test(el_1.value) || el_1.value.length < 4 ||
!el_2 || !el_2.value || !allNumeric.test(el_2.value) || el_2.value.length < 4 ||
!el_3 || !el_3.value || !allNumeric.test(el_3.value) || el_3.value.length < 4 ||
!el_4 || !el_4.value || !allNumeric.test(el_4.value) || el_4.value.length < 4 ) { resultCodes.push(-2); }//check 2: error
else { resultCodes.push(2); }//check 2: pass
//Date validation
var today = new Date();
var expMonth = $('card_exp_month');
var expYear = $('card_exp_year');
expMonth = (!expMonth || !expMonth.value || !allNumeric.test(expMonth.value)) ? -1 : parseInt(expMonth.value-1);//Convert to index-origin:zero
expYear = (!expYear || !expYear.value || !allNumeric.test(expYear.value)) ? 0 : parseInt(expYear.value);
if( expMonth === -1 || expYear === 0 || expYear < today.getYear() ||
(expYear === today.getYear() && expMonth < today.getMonth()) ) { resultCodes.push(-3); }//check 3: error
else { resultCodes.push(3); }//check 3: pass
//Error indication
var rtnVal = true;
for(var i=0; i<resultCodes.length; i++){
var el = $('msg'+Math.abs(resultCodes[i]));
if(el){
el.style.color = (resultCodes[i] < 0) ? '#FF0000' : '#000000';
rtnVal = rtnVal && (resultCodes[i] > 0);
}
}
return rtnVal;
}
</script>
</head>
<body>
<div class="style3" id="payment_box">
<form name="payment" action="" method="post" onsubmit="return validate(this);">
<table id="cardDetails" align="center"><tr>
<td>Card Holder's Name :</td>
<td><input name="fname" type="text" id="fname" msg="msg1" />
<p id="msg1" class="msg">Enter the account holder's name that appears on your card.</p></td>
</tr><tr>
<td>Card Number :</td>
<td><INPUT name="card_number_field1" type="text" id="card_number_field1" size="4" maxlength="4" msg="msg2" />
<INPUT name="card_number_field2" type="text" id="card_number_field2" size="4" maxlength="4" msg="msg2" />
<INPUT name="card_number_field3" type="text" id="card_number_field3" size="4" maxlength="4" msg="msg2" />
<INPUT name="card_number_field4" type="text" id="card_number_field4" size="4" maxlength="4" msg="msg2" />
<p id="msg2" class="msg">Enter your card's 16-digit account number.</p>
</td>
</tr><tr>
<td>Card Expiry Date (mm yyyy) :</td>
<td><INPUT name="card_exp_month" type="text" id="card_exp_month" size="2" maxlength="2" msg="msg3" /> /
<INPUT name="card_exp_year" type="text" id="card_exp_year" size="4" maxlength="4" msg="msg3" />
<p id="msg3" class="msg">Date must be in the format "01 2000" and must not be earlier than the current month.</p>
</td>
</tr><tr>
<td></td>
<td><input name="submit" type="submit" value="Submit" /></td>
</tr></table>
</form>
</div>
</body>
</html>
But please don't simply trust my code. Check it thoroughly and modify if it doesn't do exactly what you want.Airshow
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
Sorry, forgot the old Date.getYear() dichotomy (IE & Safari vs the rest).
Change .getYear() to .getFullYear() in three places.Airshow
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
Thanks m-hrt,
I hope your project goes well.
Airshow
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
Lucky, I'm sure your code works but it can be much more compact by adding some simple methods to the Date object.
Date.prototype.setToMidday = function(){ this.setHours(12); this.setMinutes(0); this.setSeconds(0); this.setMilliseconds(0); return this; };
Date.prototype.isSameDateAs = function(d){ return d.setToMidday().getTime() == this.clone().setToMidday().getTime(); };
Date.prototype.compareDate = function(d){ return this.isSameDateAs(d) ? 0 : (this.clone().setToMidday().getTime() > d.setToMidday().getTime()) ? 1 : -1; };
Date.prototype.clone = function(){ return new Date(this.getTime()); };
Note: .clone() is used before .setToMidday() thus avoiding the modification of this when performing tests in .isSameDateAs() and .compareDate() .
Use as follows:
var d1 = new Date(2009, 04, 25, 01, 31, 15);//Yesterday
var d2 = new Date(2009, 04, 26, 01, 31, 15);//Today
var d3 = new Date(2009, 04, 27, 01, 31, 15);//Tomorrow
alert(d2.compareDate(d1));//Today is later than Yesterday; therefore 1
alert(d2.compareDate(d2));//Today is the same as Today; therefore 0
alert(d2.compareDate(d3));//Today is earlier than Tomorrow; therefore -1
Airshow
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372
Lucky,
Aha, thanks. I didn't know that. STB browsers are a big gap in my knowledge, so your info is also appreciated.
Airshow
Airshow
WiFi Lounge Lizard
2,683 posts since Apr 2009
Reputation Points: 321
Solved Threads: 372