• Hey! Don't you want go to home to see my new posts?

Activating option disabled in IE

Posted by Micox - Náiron J. C. G..

May 17, 2007

In Internet Explorer, the attribute "disabled" fails if used in tag option. See here a javascript to simulate the "disabled" attribute in Internet Explorer.

This code will execute and disable option in Standard browsers (FF, Op, etc):

<select>
   <option>opt 1</option>
   <option disabled="'disabled'">opt 2</option>
   <option>opt 3</option>
</select>

In IE, it will fail.

The above code, simulates the attribute "disabled" to IE, using JavaScript. Try-it:

<!--[if lte IE 7]>
<script>
function ativaOptionsDisabled(){
    var sels = document.getElementsByTagName('select');
    for(var i=0; i < sels.length; i++){
        sels[i].onchange= function(){ //pra se mudar pro desabilitado
            if(this.options[this.selectedIndex].disabled){
                if(this.options.length<=1){
                    this.selectedIndex = -1;
                }else if(this.selectedIndex < this.options.length - 1){
                    this.selectedIndex++;
                }else{
                    this.selectedIndex--;
                }
            }
        }
        if(sels[i].options[sels[i].selectedIndex].disabled){
            //se o selecionado atual é desabilitado chamo o onchange
            sels[i].onchange();
        }    
        for(var j=0; j < sels[i].options.length; j++){ //colocando o estilo
            if(sels[i].options[j].disabled){
                sels[i].options[j].style.color = '#CCC';
            }
        }
    }
}
window.attachEvent("onload", ativaOptionsDisabled)
</script>
<![endif]-->

Ok. Now its just call this function in document load

<body onload='ativaOptionsDisabled()'>

Labels: , , ,

Sorry my bad english :) .
Type a comment! The finger dont fall (15 comments).

Add to Del.icio.usDel.icio.us Digg!

Subscribe my feed

Doubts? Visit the iEvolution Web Developer Foruns

Concursos públicos

15 Comments:

Anonymous Anonymous said... June 6, 2007 5:46 AM  
Nice workaround, but the conditional comment around the function is incorrect.

The 'disabled' attribute does not work in IE7 either (e.g. its still broken)

thus the logic should be applied to IE7 and below (presuming that MS fixes it in IE8)

cheers
steve
Blogger Micox - Náiron J. C. G. said... June 6, 2007 5:55 AM  
Oooo shit. heheh

Bad IE, bad.
Thanks steve.
I'll update now.
Anonymous Anonymous said... August 8, 2007 3:26 AM  
I think that you should attach this function inside that conditional part, like:

START IF IE HERE
START SCRIPT HERE
function ativaOptionsDisabled()
{
//...
}

window.attachEvent('onload',ativaOptionsDisabled);
END OF SCRIPT HERE
END OF IF IE

What do you think? Now other browsers won't complain about missing function..

-Cursed
Blogger Micox - Náiron J. C. G. said... August 11, 2007 7:28 AM  
Yeah. Thanks anonymous.
Blogger yunloh said... August 15, 2007 11:04 AM  
Thanks for the great workaround! I changed the function to the following in order to be more robust. Also, it fixes the assumption that the next option is not disabled:

if(this.options[this.selectedIndex].disabled){
var initial_index = this.selectedIndex
var found = false
while (this.selectedIndex < this.options.length - 1) {
this.selectedIndex++
if (!this.options[this.selectedIndex].disabled) {
found = true
break
}
}
if (!found) {
this.selectedIndex = initial_index
while (this.selectedIndex > 0) {
this.selectedIndex--
if (!this.options[this.selectedIndex].disabled) {
found = true
break
}
}
}
if (!found)
this.selectedIndex = -1
}
Blogger Micox - Náiron J. C. G. said... August 16, 2007 6:54 AM  
Thanks for contribute yunloh :)
Anonymous Anonymous said... October 24, 2007 7:44 AM  
Great article, thanks a lot.
But there's a little problem. For example, a select has 3 options: A, B and C. A is disabled. When users select C and then try to select A, B becomes selected.
Here's my workaround:
if (this.options[this.selectedIndex].disabled){
if (this.previousSelectedIndex !== undefined && !this.options[this.previousSelectedIndex].disabled) {
this.selectedIndex = this.previousSelectedIndex
} else {
var initial_index = this.selectedIndex
var found = false
while (this.selectedIndex < this.options.length - 1) {
this.selectedIndex++
if (!this.options[this.selectedIndex].disabled) {
found = true
break
}
}
if (!found) {
this.selectedIndex = initial_index
while (this.selectedIndex > 0) {
this.selectedIndex--
if (!this.options[this.selectedIndex].disabled) {
found = true
break
}
}
}
if (!found)
this.selectedIndex = -1
}
}
}
this.previousSelectedIndex = this.selectedIndex
Anonymous Anonymous said... November 30, 2007 7:46 AM  
So with the contribution on October 24, 2007 7:44 AM, what is the final JS funciton?

Thank you.
Blogger Andreas Øverland said... March 11, 2008 6:55 AM  
Another workaround is to use optgroup for disabled options. Thats ok if they are permanently disabled.
Blogger vcherkassky said... March 25, 2008 5:18 AM  
I'd like to suggest you my workaround.
I had to disable those options dynamically + I'm already using onchange. Therefore I did this:

1. I had a variable for our fixIE function on the page start + enable/disable functions:

SCRIPT START

var fixIEFunction = function(object){return true;}; //this is a fuction for non-ie: it doesn't a thing

function disableElement(object) {
object.disabled = true;
object.style.color = "#CCC";
}

function enableElement(object) {
object.disabled = false;
object.style.color = "#000";
}

SCRIPT END

2. I placed our fixIE script at the end of the page:

--OUR IE CHECK--
SCRIPT START
fixIEFunction = function fixIEOnChange(object) {
if(object.options[object.selectedIndex].disabled && (object.oldValue!=null && object.oldValue!=undefined)){
object.selectedIndex = object.oldValue;
return false;
}
object.oldValue = object.selectedIndex;
return true;
}
SCRIPT END
--END IE CHECK--

In this script i override the function to act for IE.

3. Now we have to initialize our select.oldValue inside body.onload or whenever you want it to be. (You can do this someway else and also use those counting cyclic functions suggested before - but IE is also pretty slow with JS, so using property is faster).

for all selects on the page just do this:

select.oldValue = select.selectedIndex;


4. just run our function inside onChange handler:
function onChangeHandler(owner) {
if(fixIEFunction(owner)) {
//do something useful here
}
}
Blogger Michael said... June 12, 2008 7:28 AM  
I want to put in another plug for Andreas Øverland's suggestion, the optgroup tag, which I initially overlooked. I never heard of the tag myself until today, and it might be the best workaround for some.

<optgroup label="some text" > < optgroup >

It's intended to let your group options in a drop-down menu, like so.

< optgroup label="sandwiches" >
< option >PB&J</option >
< option >BLT</option >
</ optgroup >

To simulate a disabled option tag, don't put any options between the opening and closing optgroup tags. Use CSS if you want gray text.

Here are some links for more.

http://www.inquirium.net/blog/entry_157.php

http://reference.sitepoint.com/html/optgroup

http://msdn.microsoft.com/en-us/library/ms535876(VS.85).aspx

http://www.w3schools.com/tags/tag_optgroup.asp

And if this link wasn't posted for a javascript solution...

http://www.lattimore.id.au/2005/07/01/select-option-disabled-and-the-javascript-solution/
Blogger Michael said... June 12, 2008 7:30 AM  
had some cut off links in my post above...Here are sniprurl versions.

http://snipurl.com/2g797
Select, Option, Disabled And The JavaScript Solution « Post Archive « www.lattimore.id.au [www_lattimore_id_au]

http://snipurl.com/2g7a5
optGroup Object [msdn_microsoft_com]
Blogger Micox - Náiron J. C. G. said... June 13, 2008 5:04 AM  
Thanks michael, very good solution.
Blogger Daedalist said... September 15, 2008 5:29 AM  
Thanks very much! Saved my bacon in a crisis!
Anonymous Anonymous said... September 19, 2008 8:45 AM  
Hi all...
I used this posted code in this page in my application and... when I chose only one item of combobox automatically its changed to other item not disabled near the item what I chose. OK. But before I have for example 3 or 4 items disabled near one of another its permitted select one item disabled again?!?! the code what I am posting work fine:
function conserta() {

if (document.getElementsByTagName) {

var s = document.getElementsByTagName("select");

if (s.length > 0) {

window.select_current = new Array();

for (var i=0, select; select = s[i]; i++) {
select.onfocus = function(){ window.select_current[this.id] = this.selectedIndex; }
select.onchange = function(){ restore(this); }
emulate(select);
}
}
}
}

function restore(e) {

if (e.options[e.selectedIndex].disabled) {
e.selectedIndex = window.select_current[e.id];
}
}

function emulate(e) {

for (var i=0, option; option = e.options[i]; i++) {

if (option.disabled) {
option.style.color = "graytext";
}
else {
option.style.color = "menutext";
}
}

}

in body put conserta() in onload onption

(sorry about my bad english)

hugs...

Write your comment.

Links to this post:

<< Go back to Home Page to see new posts.

Micox Codes - Some Rights Reserved - Creative Commons