Forum Moderators: open

Message Too Old, No Replies

Unable to set selectedIndex value for select object.

... which has <optgroup> IE bug?

         

iProgram

8:35 am on Nov 9, 2005 (gmt 0)

10+ Year Member



I found that if I use two select objects and both of them use <optgroup> tags, IE is unable to set selectedIndex value for the fiest select object. For example:

<select id="First_Select_Object">
<optgroup label="Year 2005">
<option value="2005-1">January</option>
<option value="2005-2">February</option>
<option value="2005-3">March</option>
<option value="2005-4">April</option>
<option value="2005-5">May</option>
<option value="2005-6">June</option>
<option value="2005-7">July</option>
<option value="2005-8">August</option>
<option value="2005-9">September</option>
<option value="2005-10">October</option>
<option value="2005-11">November</option>
</optgroup>
<optgroup label="Year 2004">
<option value="2004-1">January</option>
<option value="2004-2">February</option>
<option value="2004-3">March</option>
<option value="2004-4">April</option>
<option value="2004-5">May</option>
<option value="2004-6">June</option>
<option value="2004-7">July</option>
<option value="2004-8">August</option>
<option value="2004-9">September</option>
<option value="2004-10">October</option>
<option value="2004-11">November</option>
<option value="2004-12">December</option>
</optgroup>
</select>

<select id="Second_Select_Object">
<optgroup label="Group 1">
<option value="2">Tom</option>
<option value="3">Jerry</option>
<option value="5">Marry</option>
<option value="6">John</option>
</optgroup>
<optgroup label="Group 2">
<option value="12">Gallen</option>
<option value="13">Fox</option>
<option value="24">Ed</option>
</optgroup>
</select>

If you try to select the "2005-11" item using the following code (put it at the bottom of a form_post page):

var cbo=getElementById('First_Select_Object');
cbo.selectedIndex=10;

In most case, it does not work. I tried a lot of times. Sometimes it works, sometimes it does not work. It all depends on how fast you press the submit button. However, no problem with FireFox. Any ideas for this bug?

BlobFisk

11:08 am on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi iProgram,

I'm afraid that I haven't been able to replicate this!


<script type="text/javascript">
function setSelectedIndex() {
alert(document.getElementById('testInput').value);
document.getElementById('testSelect').selectedIndex = document.getElementById('testInput').value;
}
</script>

And:


<select id="testSelect" onchange="showIndex()">
<optgroup label="Group 1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</optgroup>
<optgroup label="Group 2">
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</optgroup>
</select>
<br />
<input type="text" id="testInput" /><input type="button" id="testButton" value="Set" onclick="setSelectedIndex()" />

Dont forget that the selectedIndex will be 1 less than the value in this example, as it starts counting at 0!

HTH

Bernard Marx

11:15 am on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No bug.

Use: document.getElementById('First_Select_Object');

iProgram

12:18 pm on Nov 9, 2005 (gmt 0)

10+ Year Member



Bernard Marx, I just forgot to type "document." here. So it's not the answer :). I test my code using Firefox and Opera, no problem at all.

This is a realy boring IE bug I've ever met. To recur this bug, you have to use two <select> objects with <optgroup> tags, and you have to set "selectedIndex=" for the first select object (no problem with the second one) and you have to have a lot of lines between your <body> tag and the first <select> object. And of cause you use IE.

BlobFisk, I tried the alert() method to debug my code. No problem with the index value but IE just doesn't select it.

If I remove all <optgroup> tags, the bug will be disappear.

BlobFisk

12:36 pm on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Have you tried your code in a function and firing it on an onclick?

Also. are you getting an error symbol in IE? Or just nothing happening?

Bernard Marx

12:56 pm on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have tried, but I can't replicate this behaviour.

iProgram

1:39 pm on Nov 9, 2005 (gmt 0)

10+ Year Member



I finally replicate this bug using the following simplest code. You may save it as test.php and upload it to your server. It's already the simplest code, do not try to modify it. You have to name it as test.php and upload to a server which supports PHP.

<?
if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$s1=$_POST['s1'];
$s2=$_POST['s2'];
}
else
{
$s1 = '0';
$s2 = '0';
}
?>
<html>
<head>
<title><? echo $s1;?> - <? echo $s2;?></title>
<script type="text/javascript">
function select_cbo_by_value(id, v)
{
var cbo=document.getElementById(id);
for(var i=0; i<cbo.length; i++)
{
if(cbo.options[i].value==v)
{
cbo.selectedIndex=i;
return;
}
}
}

function sel_cbo(s1, s2)
{
select_cbo_by_value('s1', s1);
select_cbo_by_value('s2', s2);
}
</script>
</head>
<body>
<form id="frm" action="test.php" method="post">
<select id="s1" name="s1">
<optgroup label="S1">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
<option value="33">33</option>
<option value="34">34</option>
<option value="35">35</option>
<option value="36">36</option>
<option value="37">37</option>
<option value="38">38</option>
<option value="39">39</option>
<option value="40">40</option>
<option value="41">41</option>
<option value="42">42</option>
<option value="43">43</option>
<option value="44">44</option>
<option value="45">45</option>
<option value="46">46</option>
<option value="47">47</option>
<option value="48">48</option>
<option value="49">49</option>
<option value="50">50</option>
<option value="51">51</option>
<option value="52">52</option>
<option value="53">53</option>
<option value="54">54</option>
<option value="55">55</option>
<option value="56">56</option>
<option value="57">57</option>
<option value="58">58</option>
<option value="59">59</option>
</optgroup>
</select>
<select id="s2" name="s2">
<optgroup label="S2">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
<option value="33">33</option>
<option value="34">34</option>
<option value="35">35</option>
<option value="36">36</option>
<option value="37">37</option>
<option value="38">38</option>
<option value="39">39</option>
<option value="40">40</option>
<option value="41">41</option>
<option value="42">42</option>
<option value="43">43</option>
<option value="44">44</option>
<option value="45">45</option>
<option value="46">46</option>
<option value="47">47</option>
<option value="48">48</option>
<option value="49">49</option>
<option value="50">50</option>
<option value="51">51</option>
<option value="52">52</option>
<option value="53">53</option>
<option value="54">54</option>
<option value="55">55</option>
<option value="56">56</option>
<option value="57">57</option>
<option value="58">58</option>
<option value="59">59</option>
</optgroup>
</select>
<input type="submit" value="Test" />
<script type="text/javascript"><!--
sel_cbo('<? echo $s1;?>', '<? echo $s2;?>');
//-->
</script>
</form>
</body>
</html>

To replicate this bug, open this page using IE and select 59 in both combo boxes and press Test button three to six times. You will see the second combo works fine but the first one does not work. No problem if you select a smaller number like 10, 12... No problem with other browser.

Fotiman

3:36 pm on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I believe the problem is that the script is executing before the page has finished loading. So not all of the options exist yet in the second box. One way around this is to move your call to sel_cbo to the body onload event handler:
<body onload="sel_cbo('<? echo $s1;?>', '<? echo $s2;?>');">

That fixes the problem.

Bernard Marx

4:11 pm on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I still couldn't replicate the behaviour!

The possible cause, as Fotiman describes, shouldn't apply - the script is declared after the select element is closed after all - but who knows.

Fotiman's solution (for those buggy browsers somewhere) will no doubt cover it. Waiting for the onload event may, however, give you an undesireable delay. You could try putting the script after </form>.

The best solution for this may be one that doesn't rely on client-side script at all. You could generate the selects dynamically, server-side, then slap the selected attribute onto the required option element in each case.

<option value="n" selected>

Fotiman

6:58 pm on Nov 9, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I found another solution. Try setting the selected value on the option itself. So in your code where you have this:

cbo.selectedIndex=i;

Change that to this:

cbo.selectedIndex=i;
cbo.options[i].selected = true;

That seems to eliminate the strange behavior as well.

Bernard Marx

1:47 am on Nov 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<? 

function printOptions($start, $end, $iSelected)
{
for($k=$start;$k<=$end;$k++)
{
print '<option value="'.$k.'"'
. ($k==$iSelected? ' selected>':'>')
. $k . '</option>';
}
}

if($_SERVER['REQUEST_METHOD'] == 'POST')
{
$s1=$_POST['s1'];
$s2=$_POST['s2'];
}
else
{
$s1 = '0';
$s2 = '0';
}

?>
<html>
<head>
<title><? echo $s1;?> - <? echo $s2;?></title>
</head>
<body>
<form id="frm" action="test.php" method="post">
<select id="s1" name="s1">
<optgroup label="S1">
<?php printOptions(0, 59, $s1)?>
</optgroup>
</select>

<select id="s2" name="s2">
<optgroup label="S2">
<?php printOptions(0, 59, $s2)?>
</optgroup>
</select>
<input type="submit" value="Test">
</form>
</body>
</html>

iProgram

6:09 am on Nov 10, 2005 (gmt 0)

10+ Year Member



Bernard Marx, I used to use server side script but JS code is more faster. Fotiman, your code is very interesting. I put cbo.options[i].selected = true; under cbo.selectedIndex=i; line. It works in Firefox and also solved the problem in IE. But sometimes IE will report an error "Unable to set selected property, Unknown error". I also tried to put an alert box under cbo.selectedIndex=i, which can also solve this problem. So I am consider to put some lines under it which do nothing, or just remove <optgroup> tags directly.

iProgram

6:58 am on Nov 10, 2005 (gmt 0)

10+ Year Member



I tested some old codes (for example, choose a country in country list). They all have this bug under IE. And I found that it's not related with <optgroup> tags.

Fotiman

2:55 pm on Nov 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



This appears to some kind of bug in IE. However, I think I may have stumbled upon a fix.

I've made 2 changes.

1. Change the for loop to use cbo.options.length instead of cbo.length. This is not related to the bug, but just more accurate.
2. Added a check to see if the option is already selected before trying to set it. This is what actually fixes the bug.

Here is the full code (note, I also added more options to make sure it would work with even more options)


<?
if($_SERVER['REQUEST_METHOD'] == 'GET')
{
$s1=$_GET['s1'];
$s2=$_GET['s2'];
}
else
{
$s1 = '0';
$s2 = '0';
}
?>
<html>
<head>
<title><?php echo $s1;?> - <?php echo $s2;?></title>
<script type="text/javascript">
function select_cbo_by_value(id, v)
{
var cbo=document.getElementById(id);

for(var i=0; i<cbo.options.length; i++)
{
if(cbo.options[i].value==v)
{
cbo.selectedIndex=i;
if(!cbo.options[i].selected )
{
cbo.options[i].selected=true;
}
return;
}
}
}

function sel_cbo(s1, s2)
{
select_cbo_by_value('s1', s1);
select_cbo_by_value('s2', s2);
}
</script>
</head>
<body><!-- onload="sel_cbo('<? echo $s1;?>', '<? echo $s2;?>');"> -->
<form id="frm" action="opt.php" method="get">
<select id="s1" name="s1">
<optgroup label="S1">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
<option value="33">33</option>
<option value="34">34</option>
<option value="35">35</option>
<option value="36">36</option>
<option value="37">37</option>
<option value="38">38</option>
<option value="39">39</option>
<option value="40">40</option>
<option value="41">41</option>
<option value="42">42</option>
<option value="43">43</option>
<option value="44">44</option>
<option value="45">45</option>
<option value="46">46</option>
<option value="47">47</option>
<option value="48">48</option>
<option value="49">49</option>
<option value="50">50</option>
<option value="51">51</option>
<option value="52">52</option>
<option value="53">53</option>
<option value="54">54</option>
<option value="55">55</option>
<option value="56">56</option>
<option value="57">57</option>
<option value="58">58</option>
<option value="59">59</option>
<option value="60">60</option>
<option value="61">61</option>
<option value="62">62</option>
<option value="63">63</option>
<option value="64">64</option>
<option value="65">65</option>
<option value="66">66</option>
<option value="67">67</option>
<option value="68">68</option>
<option value="69">69</option>
<option value="70">70</option>
<option value="71">71</option>
<option value="72">72</option>
<option value="73">73</option>
<option value="74">74</option>
<option value="75">75</option>
<option value="76">76</option>
<option value="77">77</option>
<option value="78">78</option>
<option value="79">79</option>
<option value="80">80</option>
<option value="81">81</option>
<option value="82">82</option>
<option value="83">83</option>
<option value="84">84</option>
<option value="85">85</option>
<option value="86">86</option>
<option value="87">87</option>
<option value="88">88</option>
<option value="89">89</option>
<option value="90">90</option>
<option value="91">91</option>
<option value="92">92</option>
<option value="93">93</option>
<option value="94">94</option>
<option value="95">95</option>
<option value="96">96</option>
<option value="97">97</option>
<option value="98">98</option>
<option value="99">99</option>
</optgroup>
</select>
<select id="s2" name="s2">
<optgroup label="S2">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="18">18</option>
<option value="19">19</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="28">28</option>
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
<option value="33">33</option>
<option value="34">34</option>
<option value="35">35</option>
<option value="36">36</option>
<option value="37">37</option>
<option value="38">38</option>
<option value="39">39</option>
<option value="40">40</option>
<option value="41">41</option>
<option value="42">42</option>
<option value="43">43</option>
<option value="44">44</option>
<option value="45">45</option>
<option value="46">46</option>
<option value="47">47</option>
<option value="48">48</option>
<option value="49">49</option>
<option value="50">50</option>
<option value="51">51</option>
<option value="52">52</option>
<option value="53">53</option>
<option value="54">54</option>
<option value="55">55</option>
<option value="56">56</option>
<option value="57">57</option>
<option value="58">58</option>
<option value="59">59</option>
<option value="60">60</option>
<option value="61">61</option>
<option value="62">62</option>
<option value="63">63</option>
<option value="64">64</option>
<option value="65">65</option>
<option value="66">66</option>
<option value="67">67</option>
<option value="68">68</option>
<option value="69">69</option>
<option value="70">70</option>
<option value="71">71</option>
<option value="72">72</option>
<option value="73">73</option>
<option value="74">74</option>
<option value="75">75</option>
<option value="76">76</option>
<option value="77">77</option>
<option value="78">78</option>
<option value="79">79</option>
<option value="80">80</option>
<option value="81">81</option>
<option value="82">82</option>
<option value="83">83</option>
<option value="84">84</option>
<option value="85">85</option>
<option value="86">86</option>
<option value="87">87</option>
<option value="88">88</option>
<option value="89">89</option>
<option value="90">90</option>
<option value="91">91</option>
<option value="92">92</option>
<option value="93">93</option>
<option value="94">94</option>
<option value="95">95</option>
<option value="96">96</option>
<option value="97">97</option>
<option value="98">98</option>
<option value="99">99</option>
</optgroup>
</select>
<input type="submit" value="Test" />

</form>
<script type="text/javascript"><!--
sel_cbo('<? echo $s1;?>', '<? echo $s2;?>');
//-->
</script>
</body>
</html>

iProgram

3:00 pm on Nov 10, 2005 (gmt 0)

10+ Year Member



Fotiman, I tried your first suggestion (body onload) and it can solve this bug directlt.

Fotiman

3:06 pm on Nov 10, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



That it does.

I would still include the check to see if it's already selected, though, just in case you ever decide to put it somewhere other than the body onload event handler.

iProgram

9:09 am on Nov 11, 2005 (gmt 0)

10+ Year Member



cbo.selectedIndex=i;
if(!cbo.options[i].selected )
{
cbo.options[i].selected=true;
}
return;

Sometimes still got "Unable to set selected property, Unknown error" in IE. It seems the body onload is the only solution.