views:

70

answers:

2

I have a SELECT list that I populate based on the results of an ajax call, then select one of the options based on a previously set variable. This works great on IE8, but on IE6 it does not.

Here is the original function:

function LoadCategories(jdata)
{
    var options = '';
    for (var i = 0; i < jdata.length; i++)
    {
        options += '<option value="' + jdata[i].CategoryName + '">' + jdata[i].CategoryName + '</option>';
    };
    $("select#categorySelect").html(options);
    $("select#categorySelect").val(currentPatientCategory).attr('selected',true);
};

On IE6, as is, this generates an error: "Could not set the selected property. Unspecified error."

IF I change the last statement to:

setTimeout('$("select#categorySelect option[value=" + currentPatientCategory + "]").attr("selected", true)', 1000);

This seems to work. I also tried changing the .html() to use .append(), .appendTo() using the appropriate syntax for those. I also tried using a variable for the selected item with no sucess. Again, they work on IE8 but not IE6. Putting an alert() prior to the selected value setting also works. It seems as if the options are not being placed in the list fast enough for the next statement to actually find them unless I delay the selection in some manner.

Any way to get this working correctly without some "workaround" like the setTimeout or moving the select somewhere else, effectivly delaying its execution for a bit?

Note: if I change the 1000 to 100 in the setTimeout, it works part of the time and part not thus I do not fully trust this solution either.

Using jQuery 1.4.2

Note: Client base dictates IE6 be supported due to older computers and update regulations/challenges in a very strict set of environments.

EDIT: Note I finally got to the end of this. There was a race condition that existed between the generation of some data via ajax and the use that manifested itself in IE6. I resolved by moving some statements around within my code to bullet proof the solution against unresolved data objects generated as such. Many thanks to posters as it pointed me in a viable direction to resolve this.

A: 

I can't even believe that this would work using .html() instead of .append() or .appendTo(). What you are basically doing is to overwrite the html code from the select element itself.
So you really should use .append().

Even more odd sounds the setTimeout() thing.

I guess what you are looking for is to replace this line:

$("select#categorySelect").val(currentPatientCategory).attr('selected',true);

with this:

$("select#categorySelect").find('option').eq(currentPatientCategory).attr('selected', 'selected');

..and don't forget to use .append()..

Ref.: .append(), .eq()

jAndy
As I noted the .append or .appendTo do not solve the issue and DO work on IE8 (the .html does as well) having tried them all in various forms. I will give your selection a shot!
Mark Schultheiss
Accepting this answer as the one that helped me the most. Editing my question to show the resolution.
Mark Schultheiss
A: 
$("select#categorySelect").val(currentPatientCategory).attr('selected',true);

val(currentPatientCategory) sets the selected option to the one whose value matches currentPatientCategory. This is OK as it is, you don't have to go searching for the right option element to set selected on.

I have no idea what the chained .attr call is for. A <select> has no selected property. I guess this is what the error is trying to tell you.

options += '<option value="' + jdata[i].CategoryName + '">' + jdata[i].CategoryName + '</option>';

This is dangerous. You include some text in HTML markup without HTML-escaping it. If there is a <, & or " character in that text your markup will break, and if the text is user-submitted you have a cross-site scripting security problem.

If you create HTML including text strings, you must HTML-escape these characters to &lt;, &amp; and &quot; respectively. But it is generally easier to use property-setting methods to set them instead of mucking around with markup:

$('#categorySelect').empty();
for (var i= 0; i<jdata.length; i++) {
    var option= $('<option/>', {text: jdata[i].CategoryName, val: jdata[i].CategoryName});
    $('#categorySelect').append(option);
}

However even simpler is the old-school DOM way:

var options= $('#categorySelect')[0].options;
options.length= 0;
for (var i= 0; i<jdata.length; i++)
    options[i]= new Option(jdata[i].CategoryName);
bobince
Understood about the HTML escape - not in scope here, but that data comes from the database and is not subject to that issue, nor is it user submitted or editable.
Mark Schultheiss
reference: http://www.w3.org/TR/html401/interact/forms.html#h-17.6.1 regarding the "selected" attribute.
Mark Schultheiss