Reputation: 34168
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.
Upvotes: 2
Views: 1472
Reputation: 536369
$("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 <
, &
and "
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);
Upvotes: 0
Reputation: 235992
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()
..
Upvotes: 1