Disabling HTML <option>s
If browsers worked as they should it would be pretty simple to disable some of the options in a select list:
<select> <option>Enabled</option> <option disabled>Disabled</option> </select>
Of course IE doesn't support this part of the spec, and it's not included in the IE 7 beta, so it's unlikely it will be supported in the near future. So, one option that makes IE behave similarly to the disabled options is to replace them with <optgroup> tags. The <optgroup>s cannot be selected and with a little CSS they look like disabled options. However, the static solution suggested didn't work for me since I needed to be able to disable or enable options at runtime. So, with a little JavaScript (and the help of MochiKit's DOM functions) the options can be enabled or disabled dynamically:
var selectStyleDisabled = function(select) { forEach(select.options, function(opt) { if (opt.disabled) { var optgroup = OPTGROUP(); updateNodeAttributes(optgroup, { label: opt.innerHTML, style: { color: 'graytext' }}); optgroup._option = opt; swapDOM(opt, optgroup); } }); forEach(select.getElementsByTagName("OPTGROUP"), function(optgroup) { var option = optgroup._option; if (option && !option.disabled) { swapDOM(optgroup, option); } }); }; addLoadEvent(function() { var selects = currentDocument().getElementsByTagName("SELECT"); forEach(selects, function(select) { select._onfocus = select.onfocus; select.onfocus = function() { selectStyleDisabled(this); if (this._onfocus) return this._onfocus(); return true; } selectStyleDisabled(select); }); });
The display of disabled options is updated in the "onfocus" method to make sure that changes in the disabled state of the options is reflected before the <select> is displayed again. Disabling options can be done directly to any of the option elements such as:
select.options[0].disabled = true;
However, a little care needs taken to re-enable options, since the <optgroup>s aren't in the "options" attribute of the <select>. The original option needs reenabled by accessing it through the "_option" attribute added to the <optgroup> element:
// reenable all disabled options in standards-compliant browsers forEach(select.options, function(option) { option.disabled = false; }); // reenable all disabled options in IE forEach(select.getElementsByTagName("OPTGROUP"), function(optgroup) { optgroup._option.disabled = false; });
To make sure that this IE hack only gets loaded in IE, put it in a .js file and wrap it in an IE conditional comment:
<!--if lt IE 8]> <script type="text/javascript" src="select-ie-disabled-options.js"></script> <![endif]-->