Javascript Question

B

beguigne

Below is a snippet of a crude date picking routine for a form. I am a
novice at this so, I am hitting my head at why when I select the day,
the onChange event gives me a blank. What am I missing?

Regards,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<SCRIPT LANGUAGE="JavaScript">
<!-- Original: Ben McFarlin ([email protected]) -->
<!-- Web Site: http://sites.netscape.net/mcfarlin -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin
function populate(objForm,selectIndex)
{
timeA = new
Date(objForm.year.options[objForm.year.selectedIndex].text,
objForm.month.options[objForm.month.selectedIndex].value,1);
timeDifference = timeA - 86400000;
timeB = new Date(timeDifference);
var daysInMonth = timeB.getDate();
for (var i = 0; i < objForm.day.length; i++)
{
objForm.day.options[0] = null;
}
for (var i = 0; i < daysInMonth; i++)
{
objForm.day.options = new Option(i+1);
}
document.f1.day.options[0].selected = true;
}

function getYears() {

// You can easily customize what years can be used
var years = new Array(2005,2006,2007)

for (var i = 0; i < document.f1.year.length; i++)
{
document.f1.year.options[0] = null;
}
timeC = new Date();
currYear = timeC.getFullYear();
for (var i = 0; i < years.length; i++)
{
document.f1.year.options = new Option(years);
}
document.f1.year.options[2].selected=true;
}
window.onLoad = getYears();
// End -->
</script>

</head>

<body>
<center>
<form name=f1>
<table border=0>
<tr>
<td align=center>
<select name=year
onChange="populate(this.form,this.form.month.selectedIndex);">
<option value="05" selected>2005</option>
<option value="06">2006</option>
<option value="07">2007</option>
<option value="08">2008</option>
</select>

<select name=month onChange="populate(this.form,this.selectedIndex);">
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>

<select name=day onChange="alert
(document.forms[0].day.options[document.forms[0].day.selectedIndex].value);">
<!-- ERROR -->
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
</select>
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
 
R

RobG

Below is a snippet of a crude date picking routine for a form. I am a
novice at this so, I am hitting my head at why when I select the day,
the onChange event gives me a blank. What am I missing?

Regards,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<SCRIPT LANGUAGE="JavaScript">

The language attribute is depreciated, type is required:

<!-- Original: Ben McFarlin ([email protected]) -->
<!-- Web Site: http://sites.netscape.net/mcfarlin -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin

HTML comments inside script elements were introduced to hide the content
from browsers that did not know about script elements. It is extremely
unlikely that any such browser is still in use - browsers that don't
have scripting support know to ignore the content of script elements.

Using HTML comments delimiters for extensive comments in a script is
dangerous and may cause problems even for browsers that would otherwise
ignore them. AFAIK their use is only tolerated at the start before any
actual script statements. Use script comment delimiters inside script
elements.
function populate(objForm,selectIndex)

'selectIndex' is never used so it can be removed.

function populate( objForm )

{
timeA = new
Date(objForm.year.options[objForm.year.selectedIndex].text,
objForm.month.options[objForm.month.selectedIndex].value,1);

Code should be manually wrapped at about 70 characters so that it can be
cut and pasted without any errors being introduced. Allowing automatic
wrapping can cause considerable frustration and extra work for those who
try to help you.

Don't use tabs, use 2 or 4 spaces to indent code (it will help prevent
inappropriate wrapping).

You should not use global variables without good reason, use the 'var'
keyword when declaring variables to keep them local. You may find it
easier for maintenance if the form values are extracted to local
variables and then used in the script. A date object can be created
with just the year, the result will be a date of 1 January of the year
used. If a month is included, then you'll get the first of the month,
so in this case you can create your date with just year and month:

var year = objForm.year.options[objForm.year.selectedIndex].text;
var month = objForm.month.options[objForm.month.selectedIndex].value;
var timeA = new Date( year, month );

Also, months in JavaScript start at 0 for January, so the values in the
date select should be 0 to 11 for months 1 to 12 - saves having to
modify the month number. The 'subtract a day' method used is a neat
trick for modifying the month number and getting the days in the month,
but it's a bit obscure and hence not good for maintenance.
timeDifference = timeA - 86400000;
timeB = new Date(timeDifference);
var daysInMonth = timeB.getDate();

The above will fail for certain dates around the changeover to daylight
saving when some days have 23 hours and other times when they have 25.
A more robust method is to subtract one from the date:

var timeB = timeA;
timeB.setDate( timeB.getDate() - 1);
var daysInMonth = timeB.getDate();

But given that you already have the month and year, a suitable routine
that avoids the use of Date altogether is:

function getMonthDays(Y, M) {
return M==4 || M==6 || M==9 || M==11 ? 30 :
M==2 ? 28 + (Y%4==0 && ( Y%100!=0 || Y%400==0)) : 31 ;
}

Which I think came from Dr J's website - there are a bunch of different
methods:

for (var i = 0; i < objForm.day.length; i++)
{
objForm.day.options[0] = null;
}

This routine seems to remove the values of all the options, easier to
just set the length to 0 (which deletes all the day options):

objForm.day.length = 0;
for (var i = 0; i < daysInMonth; i++)
{
objForm.day.options = new Option(i+1);
}
document.f1.day.options[0].selected = true;
}

function getYears() {

// You can easily customize what years can be used
var years = new Array(2005,2006,2007)


This array is not used, so it can be safely removed.
for (var i = 0; i < document.f1.year.length; i++)
{
document.f1.year.options[0] = null;
}
timeC = new Date();
currYear = timeC.getFullYear();

This depends on the users' clock being accurate and the date correctly
set - neither of which can be guaranteed but may work most of the time.
for (var i = 0; i < years.length; i++)
{
document.f1.year.options = new Option(years);
}
document.f1.year.options[2].selected=true;
}
window.onLoad = getYears();


JavaScript is case-sensitive, you are after window.onload.

Using '()' on the end of the function reference means that instead of
setting the onload function to getYears, you are setting it to the
result of getYear(). i.e. getYears is run immediately. The form 'f1'
doesn't exist yet so the statement fails. Use:

window.onLoad = getYears;

Or even better, get your server to set an appropriate year (you can only
be wrong maybe one day per year when it is January 1 where you are but
December 31 where your client is - or vice versa). And include an
option for last year otherwise in the above case your user might not be
able to select their current year.

Then you can use your existing 'populate' function:

window.onload = function() { populate(document.f1); };
// End -->
</script>

</head>

<body>
<center>
<form name=f1>

You don't always need quotes around attribute values but their use is
encouraged.
<table border=0>
<tr>
<td align=center>
<select name=year
onChange="populate(this.form,this.form.month.selectedIndex);">

Since the second parameter that you pass is never used, don't send it:

onchange="populate(this.form);">

[...]

Finally, users without JavaScript can't set any dates, so you should
probably include dates up to 31 in the day select in the HTML so that
they can still select a date. A working version is below - some people
hate selecting dates and would much rather key them in.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html><head><title>play</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">

<script type="text/javascript">

function getMonthDays(y, m) {
return m==4 || m==6 || m==9 || m==11 ? 30 :
m==2 ? 28 + (y%4==0 && ( y%100!=0 || y%400==0)) : 31 ;
}

function populate( f ) {

var year = f.year.options[f.year.selectedIndex].text;
var month = f.month.options[f.month.selectedIndex].text;
var daysInMonth = getMonthDays(year, month);

f.day.length = 0;

for (var i=0; i<daysInMonth; i++) {
f.day.options = new Option( i+1, i+1, false, false);
}
f.day.options[0].selected = true;
}

window.onload = function() {
populate(document.f1);
};
</script>
</head>
<body>
<form name="f1" action="">
<table border="0">
<tr>
<td align="center">
<select name="year" onchange="populate(this.form);">
<option>2004
<option selected>2005</option>
<option>2006
<option>2007
<option>2008
</select>
<select name="month" onchange="populate(this.form);">
<option>01
<option>02
<option>03
<option>04
<option>05
<option>06
<option>07
<option>08
<option>09
<option>10
<option>11
<option>12
</select>
<select name="day" onchange="
var d = this.form.day;
alert( d.options[d.selectedIndex].value );
">
<option>1
<option>2
<option>3
<option>4
<option>5
<option>6
<option>7
<option>8
<option>9
<option>10
<option>11
<option>12
<option>13
<option>14
<option>15
<option>16
<option>17
<option>18
<option>19
<option>20
<option>21
<option>22
<option>23
<option>24
<option>25
<option>26
<option>27
<option>28
<option>29
<option>30
<option>31
</select>
</td>
</tr>
</table>
</form>

</body>
</html>
 
A

ASM

Below is a snippet of a crude date picking routine for a form. I am a
novice at this so, I am hitting my head at why when I select the day,
the onChange event gives me a blank. What am I missing?

your onchange ask to display the value of an option in an alert box
but ...
options of 'day' have no values ! !

<select name=day onChange="alert
(document.forms[0].day.options[document.forms[0].day.selectedIndex].value);">
<!-- ERROR -->
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
</select>
 
A

ASM

RobG said:
function getMonthDays(Y, M) {
return M==4 || M==6 || M==9 || M==11 ? 30 :
M==2 ? 28 + (Y%4==0 && ( Y%100!=0 || Y%400==0)) : 31 ;
}

I do not understand this function,
particulary :

M==2 ? 28 + (Y%4==0 && ( Y%100!=0 || Y%400==0))

what does : (Y%4==0 && ( Y%100!=0 || Y%400==0))
(that gives a result? isn't it only a condition?)
Which I think came from Dr J's website - there are a bunch of different
methods:

<URL:http://www.merlyn.demon.co.uk/js-date3.htm#ML>

seen there :
February :
Y%4 != 0 ? 28 : Y%100 !=0 ? 29 : Y%400 != 0 ? 28 : 29
ok it is clear
but following ... not really (operator ^ ?)

28 + (y%4==0) ^ (y%100==0) ^ (y%400==0)
28 + (!(y%4)) ^ (!(y%100)) ^ (!(y%400))
28 | !(y%4)^!(y%100)^!(y%400)
 
B

Bangalore Info

Interestingly it works fine in Mozilla .....and gives the alert properly.

Steps to do it : select the year first (say 2007) , then select the month
(say 04) and then select any number !!!!


Ajay.



ASM said:
Below is a snippet of a crude date picking routine for a form. I am a
novice at this so, I am hitting my head at why when I select the day,
the onChange event gives me a blank. What am I missing?

your onchange ask to display the value of an option in an alert box
but ...
options of 'day' have no values ! !

<select name=day onChange="alert
(document.forms[0].day.options[document.forms[0].day.selectedIndex].value);"
<!-- ERROR -->
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
</select>
 
B

Bangalore Info

Hi ,

I think I got the solution .

REPLACE
objForm.day.options = new Option(i+1);

BY
objForm.day.options = new Option(i+1,i+1);



let me know if it doesn't work,

Cheers
Ajay.


Below is a snippet of a crude date picking routine for a form. I am a
novice at this so, I am hitting my head at why when I select the day,
the onChange event gives me a blank. What am I missing?

Regards,

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<SCRIPT LANGUAGE="JavaScript">
<!-- Original: Ben McFarlin ([email protected]) -->
<!-- Web Site: http://sites.netscape.net/mcfarlin -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin
function populate(objForm,selectIndex)
{
timeA = new
Date(objForm.year.options[objForm.year.selectedIndex].text,
objForm.month.options[objForm.month.selectedIndex].value,1);
timeDifference = timeA - 86400000;
timeB = new Date(timeDifference);
var daysInMonth = timeB.getDate();
for (var i = 0; i < objForm.day.length; i++)
{
objForm.day.options[0] = null;
}
for (var i = 0; i < daysInMonth; i++)
{
objForm.day.options = new Option(i+1);
}
document.f1.day.options[0].selected = true;
}

function getYears() {

// You can easily customize what years can be used
var years = new Array(2005,2006,2007)

for (var i = 0; i < document.f1.year.length; i++)
{
document.f1.year.options[0] = null;
}
timeC = new Date();
currYear = timeC.getFullYear();
for (var i = 0; i < years.length; i++)
{
document.f1.year.options = new Option(years);
}
document.f1.year.options[2].selected=true;
}
window.onLoad = getYears();
// End -->
</script>

</head>

<body>
<center>
<form name=f1>
<table border=0>
<tr>
<td align=center>
<select name=year
onChange="populate(this.form,this.form.month.selectedIndex);">
<option value="05" selected>2005</option>
<option value="06">2006</option>
<option value="07">2007</option>
<option value="08">2008</option>
</select>

<select name=month onChange="populate(this.form,this.selectedIndex);">
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>

<select name=day onChange="alert
(document.forms[0].day.options[document.forms[0].day.selectedIndex].value);"

<!-- ERROR -->
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
<option> </option>
</select>
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
 
M

Mick White

ASM said:
I do not understand this function,
particulary :

M==2 ? 28 + (Y%4==0 && ( Y%100!=0 || Y%400==0))

what does : (Y%4==0 && ( Y%100!=0 || Y%400==0))
(that gives a result? isn't it only a condition?)


Returns "1" (true) or "0" false, in this context. (28+1) if true, (28+0)
if false.
Mick
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Thu, 18
Aug 2005 03:35:52, seen in RobG
HTML comments inside script elements were introduced to hide the content
from browsers that did not know about script elements. It is extremely
unlikely that any such browser is still in use - browsers that don't
have scripting support know to ignore the content of script elements.

That's on the assumption that the only things that consider the contents
of the page are browsers.

A date object can be created
with just the year, the result will be a date of 1 January of the year
used.

How (except for a UTC year, of course)?
But given that you already have the month and year, a suitable routine
that avoids the use of Date altogether is:

Why do that? MonLen = new Date(Y, M, 0).getDate() is obvious
enough on the second and subsequent times that it's read! However,
MonLen = new Date(Date.UTC(Y, M, 0)).getUTCDate() should be quicker.

function getMonthDays(Y, M) {
return M==4 || M==6 || M==9 || M==11 ? 30 :
M==2 ? 28 + (Y%4==0 && ( Y%100!=0 || Y%400==0)) : 31 ;
}

Which I think came from Dr J's website - there are a bunch of different
methods:

<URL:http://www.merlyn.demon.co.uk/js-date3.htm#ML>

Not there now : I think you found it here in c.l.j.


Here's a method, based on an expression said to be in Meeus but possibly
new as such tonight, for month-length in 1901-2099 :

K = 2 - (Y%4==0) // 2 - Leap, 1901-2099
MonLen = Math.floor(275*(M+1)/9) - Math.floor(275*M/9) - K*(M==2)

Also,

MonLen = M==2 ? 30-K : 30 + ( (M+10)*367%12 > 4 )

Or even better, get your server to set an appropriate year (you can only
be wrong maybe one day per year when it is January 1 where you are but
December 31 where your client is - or vice versa). And include an
option for last year otherwise in the above case your user might not be
able to select their current year.

Last year and next year, unless the server is as far as possible East or
West without crossing the Date Line?

BTW, check the present shape of the Line; I have a suspicion that it may
be possible to have locations M hours ahead of and N hours behind
Greenwich, where Math.min(M, N) = 12 and Math.max(M, N) > 12; and that
means the date can differ by 2, not that it affects your result.

Though servers should be serving UTC, and no user is much more than 12
hours from UTC.


BTW, pages js-date?.htm are now ready for DST 2007, lest it comes.
 
B

beguigne

<select name=day
onChange="alert
(document.forms[0].day.options­[document.forms[0].day.selecte­dIndex].text);">

Was the answer.

Thanks to all for the quick responses, and constructive advise.

Carlos
 
A

ASM

<select name=day
onChange="alert
(document.forms[0].day.options­[document.forms[0].day.selecte­dIndex].text);">

Was the answer.

with(document.forms[0].day) { alert(options[selecte­dIndex].text); }
 

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,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top