I’m adapting an example found here on StackOverflow for replacing the “select” component on IE7 that does not support some nice CSS layout.
The example lacks a scrollbar, so I added a div with a fixed size so the scrollbars would appear and the component would be almost complete.
My problems:
1 – On IE7 (IE9 compatibility mode) the scrollbars do not appear. Any fix for this?
2 – How do I do to the “div” to just be positioned on that location but stay in front of the other components, instead of occupying its full size?
My code/html on jsfiddle:
http://jsfiddle.net/mbarni/nTYWA/
(run it as “no wrap (head)”)
Inline code/html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<style type="text/css">
body {
font: 80% 'Quicksand-Regular', Verdana, Geneva, sans-serif;
}
select {
display: block;
margin: 0 0 10px;
width: 300px;
}
select.replaced {
width: 1px;
position: absolute;
left: -999em;
}
ul.selectReplacement {
background: #10194B;
margin: 0 0 10px;
padding: 0;
height: 1.65em;
width: 300px;
position: relative;
z-index: 1000;
}
ul.selectFocused {
background: #10194B;
}
ul.selectReplacement li {
background: #09C;
color: #fff;
cursor: pointer;
display: none;
font-size: 11px;
line-height: 1.7em;
list-style: none;
margin: 0;
padding: 1px 12px;
width: 276px;
}
ul.selectOpen li {
display: block;
}
ul.selectReplacement li.selected {
background: #10194B;
border-bottom: 1px solid #fff;
color: #fff;
display: block;
}
ul.selectOpen li.selected {
background: #10194B;
border: 0;
display: block;
}
ul.selectOpen li:hover,
ul.selectOpen li.hover,
ul.selectOpen li.selected:hover {
background: #10194B;
color: #fff;
}
div.scroll {
overflow-y: auto;
overflow-x: hidden;
height: 100px;
width: 300px;
}
</style>
<script type="text/javascript">
function selectReplacement(obj) {
obj.className += ' replaced';
var ul = document.createElement('ul');
ul.className = 'selectReplacement';
var div = document.createElement('div');
div.className = 'scroll';
div.appendChild(ul);
var opts = obj.options;
var selectedOpt = (!obj.selectedIndex) ? 0 : obj.selectedIndex;
for (var i=0; i<opts.length; i++) {
var li = document.createElement('li');
var txt = document.createTextNode(opts[i].text);
li.appendChild(txt);
li.selIndex = i;
li.selectID = obj.id;
li.onclick = function() {
selectMe(this);
};
if (i == selectedOpt) {
li.className = 'selected';
li.onclick = function() {
this.parentNode.className += ' selectOpen';
this.onclick = function() {
selectMe(this);
};
};
}
if (window.attachEvent) {
li.onmouseover = function() {
this.className += ' hover';
};
li.onmouseout = function() {
this.className =
this.className.replace(new RegExp(" hover\\b"), '');
};
}
ul.appendChild(li);
}
obj.onfocus = function() {
ul.className += ' selectFocused';
};
obj.onblur = function() {
ul.className = 'selectReplacement';
};
obj.onchange = function() {
var idx = this.selectedIndex;
selectMe(ul.childNodes[idx]);
};
obj.onkeypress = obj.onchange;
obj.parentNode.insertBefore(div,obj);
}
function selectMe(obj) {
var lis = obj.parentNode.getElementsByTagName('li');
for (var i=0; i<lis.length; i++) {
if (lis[i] != obj) {
lis[i].className='';
lis[i].onclick = function() {
selectMe(this);
};
} else {
setVal(obj.selectID, obj.selIndex);
obj.className='selected';
obj.parentNode.className =
obj.parentNode.className.replace(new RegExp(" selectOpen\\b"), '');
obj.onclick = function() {
obj.parentNode.className += ' selectOpen';
this.onclick = function() {
selectMe(this);
};
};
}
}
}
function setVal(objID,val) {
var obj = document.getElementById(objID);
obj.selectedIndex = val;
}
function setForm() {
var s = document.getElementsByTagName('select');
for (var i=0; i<s.length; i++) {
selectReplacement(s[i]);
}
}
window.onload = function() {
(document.all && !window.print) ? null : setForm();
};
</script>
</head>
<body>
<select id="unidade">
<option value="001">TEST 1</option>
<option selected value="002">TEST 2</option>
<option value="003">TEST 3</option>
<option value="004">TEST 4</option>
<option value="005">TEST 5</option>
<option value="006">TEST 6</option>
<option value="007">TEST 7</option>
<option value="008">TEST 8</option>
</select>
</body>
</html>
You’ve run into the IE7 scrolling div bug.
Remove
position: relativefromul.selectReplacementand everything works. Already tested in jsfiddle in IE9’s IE7 Browser Mode.If you find that you need the
position: relativeon the ul elements, attachposition: relativeto the containing div (div.scroll)and that also fixes things (relevant jsfiddle). Just striping position relative didn’t seem to break anything in either chrome or IE7 mode, but if you need the ul elements to not use the static model and don’t need the div to use the static, the second method works fine too in both cases.As to the second question, you can
position: relativethediv.scrolland then wrap it in aheight: 1.5emdiv as seen in this jsfiddle. The wrapping div can have positioning and z-indexing added to it as needed: note that if you need interior elements to appear higher than other siblings to the wrapper div, you will need z-indexing on the wrapper due to an IE bug relating to z-indexing on child elements versus elements sibling to an ancestor. Works in IE7 mode and in chrome.(Note that if you want to have this be an inline element, you can
display: inline-blockit with the usual caveats–appropriate jsfiddle here and IE7 fix hack withzoomand*display:inlineversion here)Edit:
Inline version with fix for text below by having the div switch between two different heights: jsfiddle. Note that this will require some playing with the heights/line heights of the ul and li elements to avoid slight displacements in height from open to close, but the basic concept is there, albeit in an inelegant way (“better” would be to simply change the div’s height attribute, or isolate the height in an additional class and only swap that class). Note that the selected element height had to be reduced and padding removed to be able to compress the div down to essentially a single line height. Reducing heights on certain elements further will allow further compression of the scroll div without ending up with scrollbars even in the closed state, if needed.