jQuery disable SELECT options based on Radio selected (Need support for all browsers)
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Okay having a bit of trouble here, wanted to disable some of the options when selecting a radio. When ABC is selected disable the 1,2 & 3 options, etc...
Ok I got the enable/disable working but a new problem has arose. The disabled options for my select box only work in FF and IE8. I have tested IE6 and the disabled is not working. I have tried to use the hide() and show() with no luck either. basically I need to hide/disable/remove the options (for all browsers) and be able to add them back if the other radio option is selected and vice versa.
CONCLUSION:
Thanks for all the solutions, most of all of them answered my original question. Much PROPS to all :)
回答1:
The proper way to achieve the functionality you want is just to remove the options. As you discovered the hard way, disabling individual options is not supported particularly well across browsers. I just woke up and feel like programming something so I whipped up a small plugin to easily filter a select based on a radio's selected ID attribute. Although the rest of the solutions will get the job done, if you are planning on doing this throughout your app this should help. If not, then I guess it's for anyone else that stumbles upon this. Here is the plugin code you could stash away somewhere:
jQuery.fn.filterOn = function(radio, values) { return this.each(function() { var select = this; var options = []; $(select).find('option').each(function() { options.push({value: $(this).val(), text: $(this).text()}); }); $(select).data('options', options); $(radio).click(function() { var options = $(select).empty().data('options'); var haystack = values[$(this).attr('id')]; $.each(options, function(i) { var option = options[i]; if($.inArray(option.value, haystack) !== -1) { $(select).append( $('
The first argument is a selector for the radio group, the second a dictionary where the keys are the radio ID to match, and the value is an array of what select option values should remain. There's a lot of things that could be done to abstract this further, let me know if you are interested and I could certainly do that.
EDIT: Also, forgot to add, according to the jQuery documentation:
In jQuery 1.3 [@attr] style selectors were removed (they were previously deprecated in jQuery 1.2). Simply remove the '@' symbol from your selectors in order to make them work again.
Improved version of the code, using regular expression to filter options based on option values. Working example here. You can edit the example by adding /edit to the URL
$(function() { $("input:radio[@name='abc123']").click(function() { // get the id of the selected radio var radio = $(this).attr('id'); // set variables based on value of radio var regexDisabled = radio == 'abc' ? /[1-3]/ : /[a-c]/; var regexEnabled = radio == 'abc' ? /[a-c]/ : /[1-3]/; var selection = radio == 'abc' ? 'a' : 1; // select all option elements who are children of id #theOptions $("#theOptions option") // filter the option elements to only those we want to disable .filter( function() { return this.value.match(regexDisabled);}) // disable them .attr("disabled","disabled") // return to the previous wrapped set i.e. all option elements .end() // and filter to those option elements we want to enable .filter( function() { return this.value.match(regexEnabled);}) // enable them .attr("disabled",""); // change the selected option element in the dropdown $("#theOptions option[value='" + selection + "']").attr("selected","selected"); }); });
EDIT 2:
Since the disabled attribute doesn't appear to work reliably across browsers, I think your only option is to remove the option elements not needed when a radio button is selected. Working Example here
$(function() { $("input:radio[@name='abc123']").click(function() { // store the option elements in an array var options = []; options[0] = ''; options[1] = ''; options[2] = ''; options[3] = ''; options[4] = ''; options[5] = ''; var radio = $(this).attr('id'); var regexEnabled = radio == 'abc' ? /[a-c]/ : /[1-3]/; // set the option elements in #theOptions to those that match the regular expression $("#theOptions").html( $(options.join('')) // filter the option elements to only those we want to include in the dropdown .filter( function() { return this.value.match(regexEnabled);}) ); }); });
or even
$(function() { // get the child elements of the dropdown when the DOM has loaded var options = $("#theOptions").children('option'); $("input:radio[@name='abc123']").click(function() { var radio = $(this).attr('id'); var regexEnabled = radio == 'abc' ? /[a-c]/ : /[1-3]/; // set the option elements in #theOptions to those that match the regular expression $("#theOptions").html( $(options) // filter the option elements to only those we want to include in the dropdown .filter( function() { return this.value.match(regexEnabled);}) ); }); });
BTW. my code uses current stable release of jQuery (1.3.2). If you are using older release, you will need to change the attribute selectors to old syntax.
option[value='1'] to option[@value='1']
回答8:
just fix the selector $("'theOptions' option[value='1']") to $("#theOptions option[value='1']") and everything will work fine