Summary
Internet Explorer 6 does not implement disabled OPTION's in a SELECT. "Select, Option, Disabled And The JavaScript Solution" talks about a solution to emulate them using JavaScript. In this article, I will show a cleaner solution using DHTML Behaviors.
Advantages
Advantages of my DHTML Behaviors solution over other JavaScript solutions are:
- No mess with JavaScript
You don't have to add JavaScript to every SELECT tag which may contain disabled options.
If you already have some complicated JavaScript, just leave them as they are. - No mess with DOM operations
If you already have some complicated DOM operations, just leave them as they are. - Only a small change in CSS
To implement the solution, you only need to make a small change to existing CSS. - Works completely transparent
The solution works as if disabled options are supported from the beginning.
You can use this solution with JSF, with which it is difficult to change output HTML.
The Solution
To demonstrate the solution, look at the three files below:
sample.html
sample.css
sample.htc
- sample.html
- sample.css
- sample.htc
sample.html
<html> <head> <link rel="stylesheet" type="text/css" href="sample.css"> </head> <body> <form> <select> <option>Option 1</option> <option>Option 2</option> <option disabled>Option 3</option> </select> </form> </body> </html>Above is a simple HTML file with disabled options. Normally, disabled options are displayed as non-disabled options in IE6. Note that external stylesheet sample.css is loaded. If you like, you can internalize it.
sample.css
select, option { behavior: url(sample.htc); }Above is a simple CSS file which will be loaded with the HTML file. DHTML Behaviors are attached to SELECT and OPTION. Actual behaviors are defined in sample.htc.
sample.htc
<?xml version="1.0" encoding="ISO-8859-1"?> <PUBLIC:COMPONENT LIGHTWEIGHT="true"> <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="onDocumentReady()" /> <PUBLIC:ATTACH EVENT="ondetach" ONEVENT="onDetach()" /> <SCRIPT type="text/javascript"> //<![CDATA[ var nLastSelectedIndex; var fOnChangeOriginal; // event handlers function onDocumentReady() { var sTag = element.tagName.toLowerCase(); if (sTag == "select") { attachEvent("onchange", onChangeSelect); attachEvent("onpropertychange", onPropertyChangeSelect); nLastSelectedIndex = element.selectedIndex; hackOnChange(); } else if (sTag == "option") { attachEvent("onpropertychange", onPropertyChangeOption); emulateOption(); } } function onDetach() { var sTag = element.tagName.toLowerCase(); if (sTag == "select") { detachEvent("onchange", onChangeSelect); detachEvent("onpropertychange", onPropertyChangeSelect); } else if (sTag == "option") { detachEvent("onpropertychange", onPropertyChangeOption); } } // function onChangeSelect() { if (element.options[element.selectedIndex].disabled) { element.selectedIndex = nLastSelectedIndex; } else { nLastSelectedIndex = element.selectedIndex; if (fOnChangeOriginal != undefined) { fOnChangeOriginal(); } } } function onPropertyChangeSelect() { var sChangedPropertyName = event.propertyName.toLowerCase(); if (sChangedPropertyName == "onchange") { hackOnChange(); } else if (sChangedPropertyName == "selectedindex") { // contributed by Zecc nLastSelectedIndex = element.selectedIndex; } } function onPropertyChangeOption() { var sChangedPropertyName = event.propertyName.toLowerCase(); if (sChangedPropertyName == "disabled") { emulateOption(); } } // hack onChange attribute of select tag function hackOnChange() { detachEvent("onpropertychange", onPropertyChangeSelect); fOnChangeOriginal = element.onchange; element.onchange = null; attachEvent("onpropertychange", onPropertyChangeSelect); } // emulate disabled option function emulateOption() { if (element.disabled) { element.style.color = "graytext"; } else { element.style.color = "menutext"; } } //]]> </SCRIPT> </PUBLIC:COMPONENT>Above is a core HTC file which defines the DHTML Behaviors for SELECT and OPTION. What it does are:
- onDocumentReady, onDetach
Initialization and cleaning up. - onChangeSelect
When a selection is changed for a SELECT, check if the selected option is disabled. If it is disabled, revert the selection. If it is not disabled, save the selectedIndex for later use, and run the original onchange event handler set by user. - onPropertyChangeSelect
When a onchange event handler is set or changed for a SELECT, save the event handler for later use and set the onchange to null. This ensures that onChangeSelect above is called, which then calls the onchange event handler set by the user. This mechanism is needed because, by the spec, a onchange event handler set in a HTML file is called before a onchange event handler in a HTC file. This makes it possible to work consistently when there is a onchange event handler in the HTML or there is JavaScript/DOM manipulations.
Contributed by Zecc:
When a selectedindex value is set or changed for a SELECT, save the value for later use. This makes it possible to work consistently when there is JavaScript/DOM manipulations. - onPropertyChangeOption
When a disabled attribute is changed for a OPTION, change the text color of the OPTION, so it will look enabled or disabled. This makes it possible to work consistently when there is JavaScript/DOM manipulations.
Download
You can download zipped files from here.
Download includes sample-javascript.html which is a little more complicated version of sample.html, to demonstrate how the solution works when there are some JavaScript/DOM manipulations.
Note that if you open HTML files from a local directory, IE will display a alert, but this will not happen when you open the files from a web server.
Download includes sample-javascript.html which is a little more complicated version of sample.html, to demonstrate how the solution works when there are some JavaScript/DOM manipulations.
Note that if you open HTML files from a local directory, IE will display a alert, but this will not happen when you open the files from a web server.
Copyright?
This solution is dedicated to the public domain.
I do have one minor suggestion. When handling properties changes for the Select, you should also handle changes to selectedIndex. This is to prevent unproper behaviour after you assign it programmatically.
===
function onPropertyChangeSelect() {
var sChangedPropertyName = event.propertyName.toLowerCase();
if (sChangedPropertyName == "onchange") {
hackOnChange();
}
else if (sChangedPropertyName == "selectedindex") {
nLastSelectedIndex = element.selectedIndex;
}
}
===
Thanks for the code. I'm assuming you are releasing it as public domain?
Yes, it's public domian. Feel free to use it. Is your suggestion also public domain? Assuming so, I have merged your code, so other people can benefit from it.
Much appreciated
it is a very quick and dirty addition
function onPropertyChangeOption() {
var sChangedPropertyName = event.propertyName.toLowerCase();
if (sChangedPropertyName == "disabled") {
emulateOption();
}
else if (sChangedPropertyName == "selected") {
emulateOption2();
}
}
function emulateOption2() {
if (element.selected) {
element.style.color = "gray";
} else {
element.style.color = "menutext";
}
}
1 - You (almost) saved my (customers) life !
2 - I have discover DHTML bevaviors (sweeet...)
You saved my day..., not to say a week!
Thanks in advance
I see people who ask how do I use a piece of javascript, or in this case an htc behavior file with PHP. When coding in PHP you need to think with an HTML mindset. If you had a regular HTML file that you were going to impliment this in, how would you do it.
Now back on track, as Apptaro added in the main post.
select, option {
behavior: url(sample.htc);
}
This can be added as CSS code in your HTNL file or as a separate included file.
SO then how do you put this into your PHP scripts. Add it in the same area that you would if you were adding it to a standard HTML file.
IF you view the source of the page generated by your script, you can probably figure it out very easily.
Any idea what might be causing this?
If we replace fOnChangeOriginal() with fOnChangeOriginal.call(element), it works again. Please feel free to incorporate this change into your code.
When using this script to disable selecting disabled options, it works fine. But when you add an onchange function to the select, that function is called with the wrong option selected. I made a little test with the onchange function just alert(this.value); (Used the suggestion provided by hk in the above post). I have an option with value 23 that is disabled. I select it, see the previous selected option being selected again but the alert shows 23.
It's not that big a deal for me, so I'm not going to suggest a solution for it as it requires too much work right now :)
Just letting you know it's there so you can fix it some day.
Line 97, char 1 (probably not your lines!)
Error: cannot set do-nothing method on that object onchange
code 0
(and my URL)
As I doubt you can reproduce in your code, I'm going to have to remove options instead of disabling ... too bad, but if you think of anything, it would be much better to use yours.
http://www.jonathanboutelle.com/mt/archives/2006/01/howto_debug_jav.html
Thanks for the awesome idea!
Table 1 Seat 1
Table 1 Seat 2
Table 1 Seat 3
Table 2 Seat 1
Table 2 Seat 2
Table 2 Seat 3
Notice the first option is disabled? In FF "Table 1 Seat 2" is automatically selected. In IE it defaults to "Table 1 Seat 1" despite this option being disabled.
{select name="seatingFORECAST?0" id="seatingFORECAST?0" onChange="updateSeat('seatingFORECAST?0')" } {option value="1:1" disabled }Table 1 Seat 1{/option}
{option value="1:2"}Table 1 Seat 2{/option}
{option value="1:3" disabled }Table 1 Seat 3{/option}
{option value="2:1"}Table 2 Seat 1{/option}
{option value="2:2"}Table 2 Seat 2{/option}
{option value="2:3"}Table 2 Seat 3{/option}
{/select}
I'm running into a problem when I specify an onchange handler in a tag attribute of a select element. thx so mutch
thx for interesting reading :)
cheers
When a value in a dropdownlist with autopostback is selected, nothing happens. Setting a breakpoint in the code-behind reveals that no postback is ever generated. When disabling the css instruction, everything works as before, so this is clearly an issue with the behavior file.
Any ideas, anyone?
1. Performance bottleneck when there are a lot of dropdowns.
2. An a4j onchange event is not being triggered when in a different form within the same page. It was working fine without this behavior.
Thanks.
I should like implement only on one select box i try to chage style like this but this don't work
select#nstatus, option#nstatus {
behavior: url(sample.htc);
}
Thnks
Great hack!
Javaの合計、他のカーディガンダウン大きい、また、モンクレールジャケットGammeルージュ、さらにリリースで実際のヒョウ柄も、この年の周辺写真と焼けるように暑いタータンで生産されますが、バーバリー単にホットはるばる髪のブーツと一緒にカーディガンダウンと一緒に彼らならば、信じられないほど快適で人に向かって、それはそう目を引く。
薄いハーネスファッショナブル、バーバリープローサム、衣装ほぼすべてのスリップと冬のシーズンは、トリム胃のいくつかの並べ替えが出て来ました。ストレートダウンジャンパー、バーバリー コート レディースより曲線美長ったらしいに行く。また、ストレートカーディガンファッションペンスカートダウン、また襞飾り付きのコートの短いセクション内で、エミュレーションを持つことが非常に当為があり、また、英語のガソリン冬期に接続規制にもかかわらず、非常にエレガントであります。
ピーターPilottoは短いのではなく3次元効果のRuプリントに専念どんな厚いジャケット機能と同じように、季節の特別な形状の極めて正常な感覚で絶望感を発揮する排他的なかなり大きな設計低いコート、バーバリー ショルダーバッグ画像上下のカーディガンを分離で使用されているコレクションのいくつかの並べ替え。 Rundletまた、トレンディ、まだ装飾が置かれ、それは、成分が最も人気の9月であることです。
ديكورات جبس
Decoration
home decoration
decor
ديكور
كرانيش جبس
http://www.betcomegypt.com/home.php