Thursday, May 24, 2007

Drop Down List ignores zIndex

As you may know HTML Drop Down List (FORM INPUT TYPE=SELECT) don't play nice with all the other HTML elements. Specifically, the drop down list does render like any other element. It is actually rendered on top of the other HTML because it is rendered using the Operating System's native Drop Down List. This is why it looks different on a Mac vs. a PC vs. UNIX, etc. This causes problems when you want to put an absolutely positioned DIV on top of the drop down list to hide it, or fade the page, etc. The solution I came up with is a bit of smoke and mirrors approach. Basically, use JavaScript to hide the Drop Down List, then get its parent element and add a dynamically created DIV in its place. I use CSS to make the DIV look like a Drop Down List. This solution could be improved to have different styles for each of the Operating Systems. Also, note I was not able to get an accurate size of the Drop Down List in FireFox (it works fine in IE). So, just get the size of the parent node and set the width of the DIV to that. It is not perfect for FireFox, but it is reasonable for what I was doing. Here is the CSS entry you will need to make the DIV look like a Drop Down List. .ReadOnlyDDL { font-family: Tahoma, Arial, Helvetica; font-size: 12px; font-weight: normal; text-align:left; background: white; border: 1px solid #000; padding-left: 5px; padding-right: 5px; border-color: #7f9db9; border-width: 1px; background: right no-repeat url(images/ddl.png); } The remainder of this page is the JavaScript requires to hide the Drop Down List, create a DIV dynamically. function HideDDL(ddl) { var roid = ddl.id + "RO"; // make sure elements don't alread exist before creating a new one if (document.getElementById(roid) == null) { ddl.style.display = "none"; var parent = ddl.parentNode; // for some reason the clientWidth is 10px different than expected var width = ddl.clientWidth - 10; // makes it look like the standard height for DDL var height = "17px"; // needed for FireFox if (width == null width == 0) { width = parent.offsetWidth; } var ro = CreateDIV(roid, width, height); // copy the selected value to the div text ro.innerHTML = GetSelectedText(ddl); //format div to look like a drop down list ro.className = "ReadOnlyDDL"; parent.appendChild(ro); } } function CreateDIV(id, width, height) { var newdiv = document.createElement('div'); newdiv.setAttribute('id', id); // set location and dimensions newdiv.style.width = width; newdiv.style.height = height; return newdiv; } function GetSelectedText(ddl) { return ddl.options[ddl.selectedIndex].text; } This is not strictly required, but is nice if you want to hide all Drop Down Lists on the page. function HideAllDropDownLists() { var elements = document.forms[0].elements; for (var i=0; i<elements.length; i++) { if (elements[i].type == "select-one") { HideDDL(elements[i]); } } }

3 comments:

Anonymous said...

This is because dropdown list is windowed element in IE...

"In IE6, the HTML SELECT element was implemented through the Windows Shell ListBox and Combobox controls. Some key features were missing in the old version of the SELECT element, such as proper support for z-index, TITLE support, and zoom. Web developers had to write complex CSS and scripts to workaround these issues." - from here http://blogs.msdn.com/ie/archive/2006/01/17/514076.aspx

For the asp.net. One of the solutions - to use some custom control instead of DropDownList, for example this one Sakura DropDown (sakuraui.com) .


Also, Telerik (telerik.com) suggest cool controls and dropdown too.

Brent V said...

That is a great link to IE7 changes and alternate solutions. Thank you for the feedback.

Blogger said...

If you are looking into earning cash from your websites by popup advertisments, you should run with one of the biggest companies: Clickadu.