Date Validation for 3 Dropdowns!?

A

Ash

Hi everyone,

This problem has been puzzling me for a fair time now, and has severely
frustrated me!! Perhaps I'm just not getting the syntax right, but the
problem is rather simple...

Take a look at:
http://www.gasthofreiner.com/

The small booking form on the left, we're using the same one, but we need to
add javascript validation to ensure the following...

- That a date cannot be selected thats in the past
- That an invalid date cannot be selected, i.e. Feb 30th

I would also like it if when you make a selection in the first box, it
mirrors it to the second, but perhaps a day later? I think this may be a
little tricky?

REALLY appreciate anyones help, I've tried so many scripts, and just cannot
get one working.

Cheers, Ash
 
A

Ash

Actually, here's the lump of javascript that the form uses, you can see some
Javascript that I tried to make sure one date wasn't before the other...but
it didn't work!?

------------

<SCRIPT language="JavaScript" TYPE="text/javascript">
function doCheckAvail(){
if(validateFields()){
var form = document.myForm;

//collect your screen data
var arrDay = form.ARRIVAL_DAY.value;
var arrMon = form.ARRIVAL_MONTH.value;
var arrYear = form.ARRIVAL_YEAR.value;
var depDay = form.DEPARTURE_DAY.value;
var depMon = form.DEPARTURE_MONTH.value;
var depYear = form.DEPARTURE_YEAR.value;
var adult = form.ADULTS.value;
var child = form.CHILDREN.value;

var chainCode = "vones";
var hotelCode = "<%= TheHotelCode %>";
var email = "<%= TheHotelEmail %>";
var website = "http%3a%2f%2fwww.<%= TheHotelWebsite %>";
var barServer =
"https://agent.synxis.com/bar/BarServlet?selector=Login";


//start creating the url
var url = barServer+
"&cid="+chainCode+ //your chain code
"&hid="+hotelCode+ //your hotel code
"&hea="+email+ //your hotel contact email
"&url="+website+ //your hotel website
"&locale=en_GB"+ //the locale you are in
"&checkAvailability=true"+ //alerts that you are
going to the room page
"&bam="+arrMon+ //arrival month
"&bad="+arrDay+ //arrival day
"&bay="+arrYear+ //arrival year
"&bdm="+depMon+ //departure month
"&bdd="+depDay+ //departure day
"&bdy="+depYear+ //departure year
"&noa="+adult+ //# of adults
"&noc="+child; //# of children

//now pop-up the new window with this url.
document.location = url;
// window.open(url, "BAR",
"width=778,height=600,status=yes,resizable=yes,scrollbars=yes");
}
else{
alert("You must enter valid information");
}
}

function validateFields() {

// ASH: Concatenate the two dates into single variables - OR AT LEAST
TRY!!!
// var form = document.myForm;

// var arrDay = parseInt(form.ARRIVAL_DAY.value);
// var arrMon = parseInt(form.ARRIVAL_MONTH.value);
// var arrYear = parseInt(form.ARRIVAL_YEAR.value);
// var depDay = parseInt(form.DEPARTURE_DAY.value);
// var depMon = parseInt(form.DEPARTURE_MONTH.value);
// var depYear = parseInt(form.DEPARTURE_YEAR.value);


// var TheFromDate = arrDay+"/"+arrMon+"/"+arrYear
// var TheToDate = depDay+"/"+depMon+"/"+depYear

// if (TheFromDate) > (TheToDate) {
// alert('The Date of Arrival must be prior to the Date of Departures')
// alert(TheFromDate+" & "+TheToDate)
// }

return true;
}

</SCRIPT>
 
M

Michael Winter

Ash said:
Actually, here's the lump of javascript that the form uses, [...]

Rather than using that code to create the submission, why don't you just
submit the form properly?

function isValidDate(dt, y, m, d) {
return (y == dt.getFullYear()) && (m == dt.getMonth())
&& (d = dt.getDate());
}

function isValidSubmission(form) {
var elem = form.elements,
now = new Date(),
y, m, d, arr, dep;

arr = new Date(
y = +elem.bay.value,
m = elem.bam.value - 1,
d = +elem.bad.value
);
if(!isValidDate(arr, y, m, d)) {
/* Arrival date is not valid. */
return false;
}
if(arr <= now) {
/* Arrival date is before today. */
return false;
}

dep = new Date(
y = +elem.bdy.value,
m = elem.bdm.value - 1,
d = +elem.bdd.value
);
if(!isValidDate(dep, y, m, d)) {
/* Departure date is not valid. */
return false;
}
if(dep < arr) {
/* Departure date is before arrival date. */
return false;
}
return true;
}

<form method="get"
action="https://agent.synxis.com/bar/BarServlet?selector=Login"
onsubmit="return isValidSubmission(this);">
<input name="cid" type="hidden" value="vones">
<input name="hid" type="hidden" value="<%= TheHotelCode %>">
<input name="hea" type="hidden" value="<%= TheHotelEmail %>">
<input name="url" type="hidden"
value="http://www.<%= TheHotelWebsite %>">
<input name="locale" type="hidden" value="en_GB">
<input name="checkAvailability" type="hidden" value="true">
<input name="noc" type="hidden" value="0">

<!-- Arrival month -->
<select name="bam" size="1">
<!-- ... -->
</select>
<!-- Arrival day -->
<select name="bad" size="1">
<!-- ... -->
</select>
<!-- Arrival year -->
<select name="bay" size="1">
<!-- ... -->
</select>

<!-- Departure month -->
<select name="bdm" size="1">
<!-- ... -->
</select>
<!-- Departure day -->
<select name="bdd" size="1">
<!-- ... -->
</select>
<!-- Departure year -->
<select name="bdy" size="1">
<!-- ... -->
</select>

<!-- Number of adults -->
<select name="noa" size="1">
<!-- ... -->
</select>
</form>

The number of children (noc) is included amongst the hidden elements as
you haven't provided any way to input that information.

At the present moment, an arrival date that matches the current day will
be considered invalid. Changing it to be valid is not trivial. Are there
enough hours left in the day to process the booking? If the visitor is
thousands of miles away (and you don't know if they are or not), did
they really intend to book today?
//now pop-up the new window with this url.

If you really do want to use a pop-up, then you could include this function:

function submitToPopup(form) {
if('function' == typeof this.open) {
this.open(
'',
form.target,
'width=778,height=600,status,resizable,scrollbars
);
}
return true;
}

alter the submit listener to:

onsubmit="return isValidSubmission(this) && submitToPopup(this);"

and add a target attribute to the FORM element:

<form target="booking" ...>

[snip]

Hope that helps,
Mike
 
M

Mick White

Ash said:
Actually, here's the lump of javascript that the form uses, you can see some
Javascript that I tried to make sure one date wasn't before the other...but
it didn't work!?

------------
http://www.mickweb.com/b_and_b/index1.html


Mick


<SCRIPT language="JavaScript" TYPE="text/javascript">
function doCheckAvail(){
if(validateFields()){
var form = document.myForm;

//collect your screen data
var arrDay = form.ARRIVAL_DAY.value;
var arrMon = form.ARRIVAL_MONTH.value;
var arrYear = form.ARRIVAL_YEAR.value;
var depDay = form.DEPARTURE_DAY.value;
var depMon = form.DEPARTURE_MONTH.value;
var depYear = form.DEPARTURE_YEAR.value;
var adult = form.ADULTS.value;
var child = form.CHILDREN.value;

var chainCode = "vones";
var hotelCode = "<%= TheHotelCode %>";
var email = "<%= TheHotelEmail %>";
var website = "http%3a%2f%2fwww.<%= TheHotelWebsite %>";
var barServer =
"https://agent.synxis.com/bar/BarServlet?selector=Login";


//start creating the url
var url = barServer+
"&cid="+chainCode+ //your chain code
"&hid="+hotelCode+ //your hotel code
"&hea="+email+ //your hotel contact email
"&url="+website+ //your hotel website
"&locale=en_GB"+ //the locale you are in
"&checkAvailability=true"+ //alerts that you are
going to the room page
"&bam="+arrMon+ //arrival month
"&bad="+arrDay+ //arrival day
"&bay="+arrYear+ //arrival year
"&bdm="+depMon+ //departure month
"&bdd="+depDay+ //departure day
"&bdy="+depYear+ //departure year
"&noa="+adult+ //# of adults
"&noc="+child; //# of children

//now pop-up the new window with this url.
document.location = url;
// window.open(url, "BAR",
"width=778,height=600,status=yes,resizable=yes,scrollbars=yes");
}
else{
alert("You must enter valid information");
}
}

function validateFields() {

// ASH: Concatenate the two dates into single variables - OR AT LEAST
TRY!!!
// var form = document.myForm;

// var arrDay = parseInt(form.ARRIVAL_DAY.value);
// var arrMon = parseInt(form.ARRIVAL_MONTH.value);
// var arrYear = parseInt(form.ARRIVAL_YEAR.value);
// var depDay = parseInt(form.DEPARTURE_DAY.value);
// var depMon = parseInt(form.DEPARTURE_MONTH.value);
// var depYear = parseInt(form.DEPARTURE_YEAR.value);


// var TheFromDate = arrDay+"/"+arrMon+"/"+arrYear
// var TheToDate = depDay+"/"+depMon+"/"+depYear

// if (TheFromDate) > (TheToDate) {
// alert('The Date of Arrival must be prior to the Date of Departures')
// alert(TheFromDate+" & "+TheToDate)
// }

return true;
}

</SCRIPT>
 
A

Ash

Rather than using that code to create the submission, why don't you just
submit the form properly?

function isValidDate(dt, y, m, d) {
return (y == dt.getFullYear()) && (m == dt.getMonth())
&& (d = dt.getDate());

Wow thanks for your detailed response, thats excellent, I really struggle
with Javascript - not to understand its logic, but to correctly set out its
syntax, stumps me every time!

I see your reasoning behind suggesting to submit the form 'properly',
trouble is the people behind the hotel booking application prefer us to
follow their basic code model, with the addition of our own validation. I'm
quite happy with this as it enables them to support any issues we have.

Taking your above function above (ValidDate), how could we simply expand on
that, so as when the user clicks CHECK/BOOK, the current script will check
that both are valid, and if either are invalid, it'll simply popup an alert
to say so?

Cheers, Ash
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated
Mon, 25 Apr 2005 11:20:50, seen in Michael
Winter said:
Ash said:
Actually, here's the lump of javascript that the form uses, [...]

Rather than using that code to create the submission, why don't you just
submit the form properly?

function isValidDate(dt, y, m, d) {
return (y == dt.getFullYear()) && (m == dt.getMonth())
&& (d = dt.getDate());
}

One does not need all three tests (possible exception is if the function
must give the right answer for 0000-02-29 (that could be fixed with
something like Arr = new Date(y+4000, m-48000, d) ), but that will
not apply, it seems, in this case).



For drop-downs in which it is not possible to select an invalid
Gregorian date, see in <URL:http://www.merlyn.demon.co.uk/js-date6.htm>.
That code requires javascript to (re)build the day control, IIRC; but
the code could be modified to put 31 days in every month by HTML and
correct that only if javascript is available.



If there is to be a selector for arrival and then one for departure, the
latter can likewise be made to offer only dates for which departure can,
or must, follow arrival.


ISTM better, rather than having to validate the customer's choice, to
arrange matters so that he can make only valid choices. Of course, if
there is a server, there should at some stage be server-side validation.


If this is a short-stay business, how about Y M D drop-downs for
arrival, then a selector for length of stay, then a display of the
resultant departure date? For each selected date, the day-of-week
should probably be shown; indeed, a D entries in a Y M D drop-down can
show not only D but also its DoW.

An OP posting via BT should surely not be using FFF order, but Y M D.
 
A

Ash

Dr John Stockton said:
JRS: In article <[email protected]>, dated
Mon, 25 Apr 2005 11:20:50, seen in Michael


Thanks for your incredibly detailed reply, my understanding of other
logical languages is fairly good, but its the actual implementation of any
javascript that my ability to get the correct syntax seems to fail - I will
give it a go, but I'm sure I'll fail in actually amending my existing page
to incorporate this code.

In the current script, you'll notice a function...

function validateFields(){
return true;
}

To keep things simple, I would like to insert a code block into this
function that will simply...

//1. Arrival date is at least today (you may have more
restrictions)
//2. Departure date is after arrival
//3. Arrival and Departure dates are valid dates.

I feel real guilty asking for this, but would it be possible to construct
the actual code that I could dump straight into this function?

Really appreciate your help, at least from there I can see how the syntax
works in the context, and perhaps learn something for the future, hehe!

Cheers, Ash
 
@

@sh

Before I try something more complex, I'm staying simple and have tried
this...

function validateFields() {

if (document.myForm.ARRIVAL_DAY.value = '02') &&
(document.myForm.ARRIVAL_MONTH.value > '28') {
alert('Invalid date');
return false;
}
else
{
return true;
}

....But it doesn't work, what am I doing wrong? I get a 'Syntax Error'.

Cheers, Ash
 
@

@sh

Ooooops, ignore my last post....I see a few errors there but thats another
story...

I'm starting from the top now and outputing the variables I'm trying to deal
with to an alert() prompt, however I'm just getting '[object]' popping up,
does this mean it cannot interpret the value??

Cheers, Ash
 
M

Mick White

@sh said:
Before I try something more complex, I'm staying simple and have tried
this...

function validateFields() {

if (document.myForm.ARRIVAL_DAY.value = '02') &&
(document.myForm.ARRIVAL_MONTH.value > '28') {
alert('Invalid date');
return false;
}
else
{
return true;
}

...But it doesn't work, what am I doing wrong? I get a 'Syntax Error'.

function validateFields() {
var d=document.myForm
if (parseInt(d.ARRIVAL_DAY.value,10) == 2 &&
d.ARRIVAL_MONTH.value > 28) {
alert('Invalid date');
return false;
}
return true;
}
Mick
 
M

Michael Winter

Ash said:
Taking your [...] function [...] (ValidDate), how could we simply expand on
that, so as when the user clicks CHECK/BOOK, the current script will check
that both are valid, and if either are invalid, it'll simply popup an alert
to say so?

You can use the original function. All you really need to do is alter
the control names I used. So, for example

elem.bay.value

would be changed to

elem.ARRIVAL_YEAR.value

There are six control references in all, used in the two Date
constructors. The sequence 'ba' should be replaced by 'ARRIVAL_' and
'bd' by 'DEPARTURE_'. The remaining characters - 'y', 'm', and 'd' - are
obviously 'YEAR', 'MONTH' and 'DAY'.

If you want to show warnings, the comments show where failures are found
in the code and what caused them. You can use the alert function to
display a string.

There really isn't that much to edit.

Mike
 
M

Michael Winter

Dr said:
JRS: In article <[email protected]>, dated
Mon, 25 Apr 2005 11:20:50, seen in Michael
Winter <[email protected]> posted :
[snip]
function isValidDate(dt, y, m, d) {
return (y == dt.getFullYear()) && (m == dt.getMonth())
&& (d = dt.getDate());
}

One does not need all three tests [...]

Perhaps not. I don't see any particular reason not to include them all,
however it would probably be better to change the order of evaluation as
the year is only likely to change in December (when input restrictions
are imposed). It would potentially shorten the time necessary to
discover invalid dates, but still add little overhead to valid ones.
[...] <URL:http://www.merlyn.demon.co.uk/js-date6.htm>.
[...] the code could be modified to put 31 days in every month by
HTML and correct that only if javascript is available.

And probably should be. I'll probably post something later.
If there is to be a selector for arrival and then one for departure, the
latter can likewise be made to offer only dates for which departure can,
or must, follow arrival.

True. However it would still be prudent to assume that such a selector
cannot be created, and 'basic' validation should still be carried out on
the client (and the server, of course).
[...] Of course, if there is a server, there should at some stage be
server-side validation.

I get the impression that the third-party service relies on client-side
validation created by its users. I'm not about to test that theory
through an account that belongs to someone else, though.

[snip]
An OP posting via BT should surely not be using FFF order [...]

FFF?

Mike
 
L

Lasse Reichstein Nielsen

Michael Winter said:
Dr John Stockton wrote:
One does not need all three tests [...]

Perhaps not. I don't see any particular reason not to include them
all, however it would probably be better to change the order of
evaluation as the year is only likely to change in December (when
input restrictions are imposed). It would potentially shorten the time
necessary to discover invalid dates, but still add little overhead to
valid ones.

A good choice. It is a rare error that changes the year and not the
month. Indeed, most non-deliberate errors will be only a few days off
(e.g., 31st of April) and will error on both date and month.

Moving the year check last will guarantee that it is only performed
for valid dates (but that goes for any of the checks if placed third).

(btw, remember to change the "=" to "==" in the date comparison).
An OP posting via BT should surely not be using FFF order [...]

FFF?

"Fred Flintstone Format", Dr. Stockton's own name for MM/DD/YY format.
<URL:http://www.merlyn.demon.co.uk/datefmts.htm>

/L
 
M

Michael Winter

Lasse Reichstein Nielsen wrote:

[snip]
(btw, remember to change the "=" to "==" in the date comparison).

Oops. Thank you. That was careless of me.

In case the OP doesn't quite know what Lasse is referring to, the
isValidDate function should read:

function isValidDate(dt, y, m, d) {
return (dt.getDate() == d) && (dt.getMonth() == m)
&& (dt.getFullYear() == y);
}

I also thought I'd take my own advice and reverse the order of the
operands so that the method call, which cannot be assigned to without
causing a run-time error, is on the left-hand side.

Mike
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Tue, 26
Apr 2005 09:30:10, seen in Ash <spam_ash@a-
hall.com> posted :
Thanks for your incredibly detailed reply, my understanding of other
logical languages is fairly good, but its the actual implementation of any
javascript that my ability to get the correct syntax seems to fail - I will
give it a go, but I'm sure I'll fail in actually amending my existing page
to incorporate this code.

In the current script, you'll notice a function...

function validateFields(){
return true;
}

To keep things simple, I would like to insert a code block into this
function that will simply...

//1. Arrival date is at least today (you may have more
restrictions)
//2. Departure date is after arrival
//3. Arrival and Departure dates are valid dates.

I feel real guilty asking for this, but would it be possible to construct
the actual code that I could dump straight into this function?

Really appreciate your help, at least from there I can see how the syntax
works in the context, and perhaps learn something for the future, hehe!


Addressing MW : if validating date drop-downs, the year and month will
be plausible, so one should only need (UNTESTED)

function ValidDate(y, m, d) { // m = 0..11 ; y m d integers, y!=0
return new Date(y, m, d).getDate() == d /* was y, m */ }

FFF = Fred Flintstone Format - M/D/Y.

Addressing Ash - here's a start, lightly tested as mentioned :


AY = "2003" ; AM = "02" ; AD = "26" // Arr
DY = "2009" ; DM = "04" ; DD = "28" // Dep

function InvalidDate(y, m, d) { // m = 0..11 ; y m d integers, y!=0
with (D=new Date(y, m, d))
return (getMonth()==m && getDate()==d) ? D : NaN /* was y, m */ }


if (!(Arr = InvalidDate(AY, AM-1, AD))) alert('Bad Arr')
if (!(Dep = InvalidDate(DY, DM-1, DD))) alert('Bad Dep')
if (Arr >= Dep) alert('Bad stay')
if (Arr < new Date()) alert('Too soon')
Stay = Math.round((Dep-Arr)/864e5)



There may be a micro-bug if the code is run at exactly midnight.

If you have a TARDIS, do not use the above code for bookings starting or
ending on 1st Jan 1970, in locations where the OS thinks the clock was
then GMT. But here, it wasn't; we had British Standard Time then ( as
BST but all year). But MS does not know that.

Maybe
return (getMonth()==m && getDate()==d) ? D : NaN /* was y, m */ }

InvalidDate needs renaming.

Only the first alert, if more than one, is necessarily valid.

If it is necessary to force D = new Date() [which is 'NOW'] to the
beginning of today or tomorrow, use D.setHours(X, 0, 0, 0) with X=0
or X=24.

NOTE : that allows a booking for Apr 27 to be made as late as Apr 26
23:59:59.99.

NOTE : remember that American clocks are generally 5-10 hours slow, and
Australian ones nearly half a day fast - if you allow foreign visitors.
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Tue,
26 Apr 2005 15:23:26, seen in Mick White
function validateFields() {
var d=document.myForm
if (parseInt(d.ARRIVAL_DAY.value,10) == 2 &&
d.ARRIVAL_MONTH.value > 28) {
alert('Invalid date');
return false;
}
return true;
}


Funny calendar you have in your part of the USA - months after the 28th
don't have a Day 2.

Take a local copy of <URL:http://www.merlyn.demon.co.uk/js-quick.htm> -
DO NOT use the web copy repeatedly, for bandwidth reasons - and you can
then easily test little bits of code before posting them.

For dates in 2001-2099, and I guess that's enough for the OP, who should
by then be promoted/sacked/retired, it should be sufficient to test that
D <= 31 - (M==4 || M==6 || M==9 || M==11) and if M==2 that
D <= 28 + (Y%4==0) .

But the test with a Date Object will be better.


GENERAL : a proportion of news posts (not only mine) uploaded to my ISP
in the last week or so have been delayed, apparently before being
offered to servers and peers; they are now appearing.
 
M

Mick White

Dr said:
<[email protected]> posted : [snip]
if (parseInt(d.ARRIVAL_DAY.value,10) == 2 &&
d.ARRIVAL_MONTH.value > 28) {
[snip]

Funny calendar you have in your part of the USA - months after the 28th
don't have a Day 2.

Oops, perhaps I have the month and the date reversed...
Take a local copy of <URL:http://www.merlyn.demon.co.uk/js-quick.htm> -
DO NOT use the web copy repeatedly, for bandwidth reasons - and you can
then easily test little bits of code before posting them.

Mea culpa. I have some trouble with your site using Safari. The date
object is, well, different.

For dates in 2001-2099, and I guess that's enough for the OP, who should
by then be promoted/sacked/retired, it should be sufficient to test that
D <= 31 - (M==4 || M==6 || M==9 || M==11) and if M==2 that
D <= 28 + (Y%4==0) .

But the test with a Date Object will be better.

I agree since you are, at most, creating 2 date objects.
Mick
 
@

@sh

Oops, perhaps I have the month and the date reversed...
function isValidDate(dt, y, m, d) {
return (dt.getDate() == d) && (dt.getMonth() == m)
&& (dt.getFullYear() == y);
}

Just to say a massive thanks to all that contributed here, I really do wish
I had the javascript understanding that you guys clearly have, its just the
syntax that gets me, and the data subtypes, I hope to get there in the end.

Its unfortunate that there are such within other threads so as to spoil the
experience for Usenet newbies. I appreciate you must get some silly
questions on here, but some must sit staring at their screen just waiting to
post their negative picky shite.

Thanks once again though for your help here, I'll stick around for a bit
incase of further troubles ;o)

p.s. it was my fault that the date/months were reversed...a typo I noticed
shortly after, hehe!

Cheers, Ash
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Tue, 26 Apr 2005
21:11:22, seen in Lasse Reichstein Nielsen
Michael Winter said:
Dr John Stockton wrote:
One does not need all three tests [...]

Perhaps not. I don't see any particular reason not to include them
all, however it would probably be better to change the order of
evaluation as the year is only likely to change in December (when
input restrictions are imposed). It would potentially shorten the time
necessary to discover invalid dates, but still add little overhead to
valid ones.

A good choice. It is a rare error that changes the year and not the
month. Indeed, most non-deliberate errors will be only a few days off
(e.g., 31st of April) and will error on both date and month.

Moving the year check last will guarantee that it is only performed
for valid dates (but that goes for any of the checks if placed third).

Omitting the year check allows the validation to be used for years given
as 00..99 meaning 1900..1999, and for years 00..99 meaning 0000..0099 if
an error for 0000-02-29 can be tolerated. It also avoids any doubt
about the availability of getFullYear.

An OP posting via BT should surely not be using FFF order [...]

FFF?

"Fred Flintstone Format", Dr. Stockton's own name for MM/DD/YY format.
<URL:http://www.merlyn.demon.co.uk/datefmts.htm>

No, not my own name, but one that I came across, possibly on the Web but
more likely in News - maybe and probably in
conjunction with FFU, the system of measurement units that the Americans
use and refer to as English (unfair to Welsh, Scots, and Irish) although
the proper name in English is Imperial Units.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top