views:

395

answers:

3

Hi guys, In my HTML page I have 2 select menus with IDs "month" and "day" - "day" is empty when the page loads, "month" has 12 options with values 1-12 corresponding to January - December.

"month" has an onchange event which calls this function:

function showOutboundDays(month)
{
if(month==4 || month==6 || month==9 || month==11)
    document.getElementById('day').innerHTML='<option value="1">1</option><option value="2">2</option>'; etc. up to 30
else if(month==2)
    document.getElementById('day').innerHTML='<option value="1">1</option>'; etc. up to 28
else 
    document.getElementById('day').innerHTML='<option value="1">1</option>'; etc. up to 31
}

(just imagine there are braces around the option tags to help you see...)

I think it's pretty clear to see what I'm trying to achieve...and everything works fine apart from the innerHTML of the select with ID "day" doesn't get filled at all, regardless of what month you pick. And I know the problem is with this stage of the function because when I change the if, elseif and else code-to-be-executed to alerts or something similar, it works fine.

Does anybody know what the problem with the innerHTML is?

Thanks

EDIT: Using Firefox 3.6

A: 

This is a known issue for IE.

KB article with workaround: http://support.microsoft.com/kb/276228

Also: dupe of: http://stackoverflow.com/questions/1293427/innerhtml-replace-does-not-reflect

EDIT: Here is my working sample based on your code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
 <title>Selects</title>
 <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
 <style rel="stylesheet" type="text/css">
 </style>
 <script>
function showOutboundDays(month) 
{ 
    if(month==4 || month==6 || month==9 || month==11) 
        document.getElementById('day').innerHTML='<option value="1">1</option><option value="2">2</option>';
    else if(month==2) 
        document.getElementById('day').innerHTML='<option value="1">3</option><option value="1">4</option>';
    else  
        document.getElementById('day').innerHTML='<option value="1">5</option><option value="1">6</option>';
}
 </script>
 </head>
<body>
    <select onchange="showOutboundDays(this.value);">
        <option value="1">January</option>
        <option value="2">February</option>
        <option value="3">March</option>
        <option value="4">April</option>
        <option value="5">May</option>
        <option value="6">June</option>
        <option value="7">July</option>
        <option value="8">August</option>
        <option value="9">September</option>
        <option value="10">October</option>
        <option value="11">November</option>
        <option value="12">December</option>
    </select>
    <br />
    <select id="day">
    </select>
</body>
</html>
David
Sorry, I should have added, I'm using Firefox
Deacon
Can you edit your post, highlight the code and click the code icon in the editor so the braces make it through correctly. Need to see exactly what you are trying to do.
David
I tested your code and it worked for me in Firefox after I removed your comments and added semicolons for each line in the if/else, etc. I can post what I modified if you still need it, but I recommend RoToRa's answer instead of using innerHTML, especially since innerHTML isn't going to work in IE
David
Would you be able to post the version of my code with your modifications? As I've just tried it after getting rid of the comments and adding the semi-colons like you said, and it still doesn't work! Thanks
Deacon
sure, will edit the answer
David
Excellent, thanks a lot for your help David :)
Deacon
+4  A: 

I would suggest simple not to use innerHTML on a select - it just seems wrong. select elements have easy to use methods to add new options:

document.getElementById('day').options.add(new Option("1", "1"))
RoToRa
+4  A: 

You should not be using innerHTML to modify tags. You should be using removeChild(element); and appendChild(element);

First you set your select box in a variable for legibility and editing purposes;

var select = document.getElementById('days');

Then you clear the select box

while ( select.childNodes.length >= 1 )
{
    select.removeChild(select.firstChild);       
}

Finally you fill it again with the appropriate values

for(var i=1;i<=days;i++)
{
    newOption = document.createElement('option');
    newOption.value=i;
    newOption.text=i;
    select.appendChild(newOption);
}

So at the end with your code and my code here you get the following:

function showOutboundDays(month, year)
{
    var days=null;

    if(month==4 || month==6 || month==9 || month==11)
        days=30;
    else if(month==2)
    {
        //Do not forget leap years!!!
        if(year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) //Provided by Justin Gregoire
        {
            days=29;
        }
        else
        {
            days=28;
        }
    }
    else 
        days=31;


    var select = document.getElementById('days');

    while ( select.childNodes.length >= 1 )
    {
        select.removeChild(select.firstChild);       
    }

    for(var i=1;i<=days;i++)
    {
        newOption = document.createElement('option');
        newOption.value=i;
        newOption.text=i;
        select.appendChild(newOption);
    }
}

Leap years are now included!

Jonathan Czitkovics
Use `newOption.text` in preference to `innerHTML`. More reliable and avoids HTML-escaping issues.
bobince
Thanks that's a good idea also.
Jonathan Czitkovics
You may want to check your logic for leap years -- they happen roughly once every 4 years.
Joe
if (year % 400 == 0 || (year % 4 == 0 else days = 28;
Justin Gregoire
Thank you for pointing it out for me and finding it too! Modified my code and left credit where its due.
Jonathan Czitkovics
Hi Jonathan,Thanks for your help - I tried putting the code in but unfortunately I just get the empty select box for days. Not quite sure what's up, I'm using Firefox 3.6 on OSX if that makes any difference
Deacon