Marcus Guinane
Marcus Guinane

Reputation: 139

jQuery/javascript - list box item deselect/show/hide not working in IE?

I have the following javascript/jquery code, the purpose of which is to -

  1. Deselect a previously selected item from the list, if the selected item value exists in an array
  2. Hide/display each list item dependent on whether they exist in the array

var list = $(row).find("select > option")

var selectedValue = $(row).find("select > option:selected")
if (selectedValue) {
    if ($.inArray(selectedValue[0].value, dependencyListItemValues) == -1) {
        alert('deselect');
        $(selectedValue).attr("selected", false);
    }
}

$(list).each(function () {
    var value = this.value;
    if (value != "") {
        if ($.inArray(value, dependencyListItemValues) > -1) {
             alert('show');
             $(this).show();
        }
        else {
             alert('hide');
             $(this).hide();
        }
    }
});    

This is working fine in chrome and firefox, but not in IE9. When running in IE, the alert lines are hit, but the following lines seemingly do nothing:

$(selectedValue).attr("selected", false);

$(this).show();

$(this).hide();    

Do I need to use alternative code so this will work in IE?

Upvotes: 1

Views: 4482

Answers (3)

Dima
Dima

Reputation: 1065

Here is a good solution:

http://ajax911.com/hide-option-elements-jquery/

Upvotes: 0

Marcus Guinane
Marcus Guinane

Reputation: 139

OK my solution was as follows ... this is based on the answer by meder (thanks!) on this question - Hide select option in IE using jQuery

Firstly, in place of this line:

$(selectedValue).attr("selected", false);

I did this:

$(row).find("select")[0].selectedIndex = -1;

And to show/hide the relevant list items, I had to first wrap those that I needed to hide in a span and then apply the .hide() command, and for those I needed to display, replace the span with the original option element:

//first we need to hide the visible list values that are not in the list of dependent list values.
//get the list values which are currently displayed, these will be the 'option' elements of the 'select' element (list).
//the hidden values are within a span so will not be picked up by this selector
var displayedListValues = $(row).find("select > option")

//loop through the displayed list values
$(displayedListValues).each(function () {
    //get the value from this 'option' element
    var displayedValue = this.value;

    //ignore empty values (first blank line in list)
    if (displayedValue != "") {
            //if the value is not in the list of dependent list values, wrap in span and apply .hide() command
            if ($.inArray(displayedValue, dependencyListItemValues) == -1) {
                $(this).wrap('<span>').hide();
            }
        }
    });

//now we need to display the hidden list values that are in the list of dependent list values.
//get the list values which are currently hidden, these will be the 'span' elements of the 'select' element (list).
//the visible values are within an 'option' so will not be picked up by this selector
var hiddenListValues = $(row).find("select > span")

//loop through the hidden list values
$(hiddenListValues).each(function () {
    //find the 'option' element from this 'span' element and get its value
    var opt = $(this).find('option');
    var hiddenValue = opt[0].value;

    //ignore empty values (first blank line in list)
    if (hiddenValue != "") {
        //if the value is in the list of dependent list values, apply .show() command on the 'option' element
        //(not sure why the .show() command works in this case?)
        //and then replace the 'span' element with the 'option' element, which is effectively removing the span wrapper
        if ($.inArray(hiddenValue, dependencyListItemValues) > -1) {
            $(opt).show();
            $(this).replaceWith(opt);
        }
    }
});

Which works fine ... although rather annoying I had to do this rather messy re-coding just because IE doesn't support .show() and .hide() of list values!!!!!

Upvotes: 0

Luca Rainone
Luca Rainone

Reputation: 16468

First: You can use list.each instead of $(list).each.

Second, you cannot hide an OPTION element in crossbrowser way. So, you must remove it (for hide) and re-create it (for show). You can store all options (and them parent) in array, like so:

var cache_options= [];
list.each(function(index) {
    cache_options.push({el:$(this), parent:$(this).parent()});
});

and after

for(var i = 0; i<cache_options.length; i++) {
    var value = cache_options[i].el[0].value;
    if (value != "") {
        if ($.inArray(value, dependencyListItemValues) > -1) {
            cache_options[i].parent.append(cache_options[i].el);
        }
        else {
            cache_options[i].el.remove();     
        }
    }
} 

Tested!

Upvotes: 1

Related Questions