IE7 select boxes: powered by fairy dust



  • Consider the following Javascript code for dynamically creating a select box populated with a set of options, and selecting one of them:

    <html>
      <head>
        <script type="text/javascript">
          function go() {
            optionNames = ['false', 'true', 'file_not_found']
            var selectBox = document.createElement('select');
            optionsByName = {}
            for (var i = 0; i < optionNames.length; i++) {
              selectBox.options[i] = new Option(optionNames[i], i);
              optionsByName[optionNames[i]] = selectBox.options[i];
            }
            document.getElementById('form').appendChild(selectBox);

            selectBox.selectedIndex; /* add magic */
           
            selectBox.selectedIndex = optionsByName['true'].index;
          }
        </script>
      </head>
      <body onload="go()">
        <form id="form">
        </form>
      </body>
    </html>

    A foolish programmer might see the /* add magic */ line, realise that it does the equivalent of "hello, this is a nice select box isn't it? Just saying.", and try to take it out. This would be a mistake, because that line is required for IE7 - otherwise it leaves the select box blank. Never mind that the select box doesn't actually have a blank option, that's just part of the magic. Obviously select boxes just take a while to warm up, or something.

    It's not the only way to supply magic, though. You can stick alert('brillant') in there instead, and that'll work nicely.



  • It would seem that optionsByName["true"].index doesn't return 1 until the select combo has had a chance to be drawn visibly to the page, or your magic has been applied. For me it returns 127218536 otherwise :) It seems to point things the way of an uninitialised pointer courtesy of Microsoft.

    Of course to prevent programmers from removing the magic line its associated comment should be more a little more descriptive :)



  • Does this work any better?

    <html>
      <head>
        <script type="text/javascript">
          function go() {
            var optionNames = ['false', 'true', 'file_not_found']
            var selectBox = document.createElement('select');
            optionsByName = {}
            for (var i = 0; i < optionNames.length; i++) {
    var opt = document.createElement('option');
    opt.label = optionNames[i];
    opt.value = i;
              selectBox.add( opt );
              optionsByName[optionNames[i]] = opt;
            }
            document.getElementById('form').appendChild(selectBox);
            selectBox.selectedIndex = optionsByName['true'].index;
          }
        </script>
      </head>
      <body onload="go()">
        <form id="form">
        </form>
      </body>
    </html>

    If so, then there's something broken in their code for assigning to the options array directly (which is corrected upon reference to .selectedIndex), and you ought to use the DOM functions instead. If not, then something is broken elsewhere.  You might be able to get away with setting it to 0 first, and then setting it to the desired index. I don't know, because I don't have IE7 handy.



  • Ah, no... document.createElement('option') has an entirely different bizarre bug. I forget exactly what it is - it's been erased from my memory and replaced with a post-it note saying "Don't use this. Ever. Use 'new Option' instead."



  • Funny, I've got dynamic select boxes code all over the place and never had to resort to any pixie dust. Not even in IE7


Log in to reply