Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why jQuery hide()/show() ruin HTML select in Chrome?

I am writing jira-plugin and I need to edit customfield on create issue screen. I use jQuery to do this. I have a problem with jQuery hide / show methods used on html select in Chrome (under Firefox works well). The problem is I have 3 different select-boxes which options depends on the option selected in the previous one. I have a function to prepare the next select list when the previous one changed.

function prepareList(code, list) {
    list.children('option').each(function() {
        if(jQuery(this).text() == code || jQuery(this).text() == 'None') {
            jQuery(this).show();
        }
        else {
            jQuery(this).hide();
        }
    });
}

code is a string which is jQuery('#previous_select option:selected').text() It works fine in many cases but sometimes it resizes the option list. Worse thing is that when the next list has only one option it is not displayed. I can see it has display: inline in html code but after I click on select triangle the dropdown list has like 2 px.

Funny fact is that it works perfectly in Firefox.
IE 8 is not even hiding/showing but it is just IE so I can understand this.
Opera 12.16 is not hiding / showing also.
Safari 5.1.7 for Windows is not hiding / showing too.

The question is which methods should I use to achieve my goal? I tried jQuery(this).css('display', 'none/inline') too and its not working also.

EDIT: JSFiddle: jsfiddle.net/7KRLE/

like image 832
patrykf Avatar asked Oct 02 '22 04:10

patrykf


2 Answers

$('#tier3').attr('disabled', true);

In order to disable an option element, you must set its disabled attribute to string 'disabled', not the boolean true.

which gives you:

$('#tier3').attr('disabled', 'disabled');

To enable it:

$('#tier3').attr('disabled', '');

or

$('#tier3').removeAttr('disabled');

IE and many other other browsers behave safely and do not allow hiding of options from the user.
About other special treatments for IE, read this article.

like image 52
Bora Avatar answered Oct 04 '22 18:10

Bora


I found the solution. It looks like jQuery hide / show is confusing Chrome and other browsers (part of them don't allow hide / show). The answer is to use jQuery.detach() and store the list in the array. If You want the whole list You just need to rebuild it from your array using jQuery.append() on your HTML select. This works well on Chrome, Opera, Safari and Firefox. IE is still a problem.

function prepareList(code, list, level) {
    if (level == 1) {
        list.children('option').each(function () {
            if ($(this).text().substring(1, 4) != code && $(this).text() != 'None') {
                $(this).detach();
            }
        });
    } else if (level == 2) {
        list.children('option').each(function () {
            if ($(this).text().substring(1, 5) != code && $(this).text() != 'None') {
                $(this).detach();
            }
        });
    } 
}

function rebuildList(list, a) {
    if(a == 2) {
        for(var i = 0; i < tempt2.length; i++) {
            $(list).append(tempt2[i]);
        }
    }
    else if(a == 3) {
        for(var i = 0; i < tempt3.length; i++) {
            $(list).append(tempt3[i]);
        }
    }
    else {
        rebuildList($('#tier2'), 2);
        rebuildList($('#tier3'), 3);
        $("#tier2").val('none');
        $("#tier3").val('none');
    }
}  

function saveList(list, a) {
    if(a == 2) {
        $(list).children('option').each(function() {
            tempt2.push($(this).detach());
        });
        rebuildList($('#tier2'), 2);
    }
    else if(a == 3) {
        $(list).children('option').each(function() {
            tempt3.push($(this).detach());
        });
        rebuildList($('#tier3'), 3);
    }
}

New JSFiddle: jsFiddle

like image 35
patrykf Avatar answered Oct 04 '22 18:10

patrykf