Editable combobox with javascript (source included) - please feedback!

O

Oliver Hoehle

Hello!

This ist the source-code for an editable combobox implemented with
HTML,CSS and Javascript.

I have tested it with IE and Mozilla. But I don't know, if it will
work in other browsers (Opera, Konqueror, etc.) So I need your
feedback...

Regards
Oliver

--- SNIP ---

<html>
<head>
<style type="text/css">
<!--
div.cbhide {
position:absolute;
visibility:hidden;
overflow:hidden;
height:0px;
}
div.cbshow {
position:absolute;
visibility:visible;
overflow:visible;
}
table.combo {
width:100%;
border: 1px solid #000000;
}
#cbtext {
background-color:#FFFF99;
}
#cbbtn{
border-color:#FFFFFF;
border-width:2px;
border-style:eek:utset;
cursor:pointer;
background-color:#CCCCCC;
text-align:center
vertical-align:middle;
margin:0px;
padding:0px;
height:100%;
}
td.passive {
color:#000000;
background-color:#FFFF99;
}
td.active {
color:#FFFFFF;
background-color:#0000FF;
}
-->
</style>

<script type="text/javascript">
<!--
function mousedown(obj) {
var select = document.getElementById('cbselect');
var temp = obj.target;
while(temp != null && temp != select) {
temp = temp.parentNode;
}
if(temp == select) {
obj.target.handleEvent(obj);
} else {
hide();
}
}

function hide() {
document.getElementById('cbselect').className='cbhide';
document.getElementById('cbbtn').onclick=show;
document.onmousedown = null;
return true;
}

function show() {
var node = document.getElementById('cbtext');
var x = Number(node.offsetLeft) + Number(document.body.leftMargin);
var y = Number(node.offsetTop) + Number(node.offsetHeight) +
Number(document.body.topMargin);
var w = Number(node.offsetWidth)
var div = document.getElementById('cbselect');
div.className='cbshow';
div.style.top = y;
div.style.left = x;
div.style.width = w;
document.getElementById('cbbtn').onclick=hide;
if(document.addEventListener) {
document.onmousedown = mousedown;
} else {
document.getElementById('cbbtn').onblur=hide;
}
}

function select(td) {
td.className='passive'
var text = td.firstChild.nodeValue;
document.getElementById('cbtext').value = text;
hide();
}
//-->
</script>
</head>
<body>
<table class="comboinput" cellspacing="0" cellpadding="0">
<tr class="comboinput">
<td class="comboinput"><input id="cbtext" type="text"
name="test"></td>
<td class="comboinput">
<button id="cbbtn" type="button"
onmousedown = "this.style.borderStyle='inset'"
onmouseup = "this.style.borderStyle='outset'"
onmouseout = "this.style.borderStyle='outset'"
onclick="show()">
<img src="open.gif">
</button>
</td>
<!-- <td class="comboinput">
<button type="button" onclick="alert('Click')">Click</button>
</td> -->
</tr>
</table>

<div id="cbselect" class="cbhide">
<table class="combo" cellspacing="0" cellpadding="0" >
<tr class="option">
<td class="passive" onMouseover="this.className='active';"
onMouseout="this.className='passive';" onClick="select(this)"
onFocus="select(this)">Apple</td>
</tr>
<tr class="option">
<td class="passive" onMouseover="this.className='active';"
onMouseout="this.className='passive';" onClick="select(this)"
onFocus="select(this)">Cherry</td>
</tr>
<tr class="option">
<td class="passive" onMouseover="this.className='active';"
onMouseout="this.className='passive';" onClick="select(this)"
onFocus="select(this)">Melon</td>
</tr>
<tr class="option">
<td class="passive" onMouseover="this.className='active';"
onMouseout="this.className='passive';" onClick="select(this)"
onFocus="select(this)">Lemon</td>
</tr>
<tr class="option">
<td class="passive" onMouseover="this.className='active';"
onMouseout="this.className='passive';" onClick="select(this)"
onFocus="select(this)">Peach</td>
</tr>
<tr class="option">
<td nowrap class="passive" onMouseover="this.className='active';"
onMouseout="this.className='passive';" onClick="select(this)"
onFocus="select(this)">Plum</td>
</tr>
</table>
</div>
</body>
</html>
 
R

RobG

Oliver said:
Hello!

This ist the source-code for an editable combobox implemented with
HTML,CSS and Javascript.

Using a table to implement a select seems silly. Why not just put a
select under the text input that is shown when the button is clicked,
then when a selection is made, hide it again and put the selected text
into the text input?

Example below.
I have tested it with IE and Mozilla. But I don't know, if it will
work in other browsers (Opera, Konqueror, etc.) So I need your
feedback...

It sort of works in Safari, but:
[...]
<style type="text/css">
<!--

Don't bother trying to hide scripts/styles
div.cbhide {
position:absolute;
visibility:hidden;
overflow:hidden;
height:0px;
}

Why change the class when you want to hide something? Just use:

elementRef.style.display = "none";
div.cbshow {
position:absolute;
visibility:visible;
overflow:visible;
}

and to show it again:

elementRef.style.display = "";

If you want to use visibility:

elementRef.style.visibility = "hidden";
elementRef.style.visibility = "visible";

[...]
function mousedown(obj) {
var select = document.getElementById('cbselect');

You should include a document.all method for old IE (see the group
faq at <URL:http://www.jibbering.com/faq>).

[...]
function hide() {
document.getElementById('cbselect').className='cbhide';
document.getElementById('cbbtn').onclick=show;
document.onmousedown = null;
return true;
}

If you just position your select in the page with HTML and simply
hide/show it by changing its display attribute, you don't need either
of these functions.

A simple function could toggle the display attribute;

function showHide(anId) {
var thing;
if (document.getElementById) {
thing = document.getElementById(anId);
} else if (document.all) {
thing = document.all[anId];
}

if (thing.style.display == '') {
thing.style.display = 'none';
} else {
thing.style.display = '';
}
}

Of course, you can remove the above completely if you use the form
elements collection or reference form elements differently (see the
code below - it doesn't use getElementById or getElementsByTagName).
function show() {
var node = document.getElementById('cbtext');
var x = Number(node.offsetLeft) + Number(document.body.leftMargin);

Attempting to locate the coordinates of an element in the page in a
cross-browser manner is problematic. But if you just put the element
in the page where you want it, then show/hide it, you don't have to do
it at all.

Document.body.leftMargin will not work in Safari (and I suspect
it's failing in all the other browsers too), try:

document.getElementsByTagName('body')[0].style.marginLeft

similarly for your attempt at "topMargin":

document.getElementsByTagName('body')[0].style.marginTop

But this is dependent on the browser supporting getElementsByTagName
and the DOM style object (so OK for IE 6 but probably not 5).


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Editable Select</title>

<script type="text/javascript">
function showHide(btn,ele) {
if (ele.style.display == 'none') {
ele.style.display = '';
btn.value = 'Hide list';
} else {
ele.style.display = 'none';
btn.value = 'Show list';
}
}

function addValue(sel,txt) {
txt.value = sel[sel.selectedIndex].value;
}
</script>

</head><body>

<form action="">
<input type="text" style="width: 150px" name="cbtext">
<input type="button" value="Show list" style="width: 10em;"
name="showHideButton" onclick="
showHide(this,this.form.fruitList);
">&nbsp;
<input type="reset">
<div style="position: relative;">
<select name="fruitList" style="display: none; position: absolute;"
onclick="
addValue(this,this.form.cbtext);
showHide(this.form.showHideButton,this.form.fruitList);
this.style.display = 'none';
">
<option value="Apple" >Apple</option>
<option value="Cherry">Cherry</option>
<option value="Melon" >Melon</option>
<option value="Lemon" >Lemon</option>
<option value="Peach" >Peach</option>
<option value="Plum" >Plum</option>
</select>
</div>
</form>
Here is some text. Here is some text. Here is some text. Here is some
text. Here is some text. Here is some text. Here is some text. Here
is some text. Here is some text. Here is some text. Here is some
text. Here is some text. Here is some text. Here is some text. Here
is some text. Here is some text. Here is some text. Here is some
text. Here is some text. Here is some text. Here is some text. Here
is some text. Here is some text. Here is some text. Here is some text.
</body>
</html>



And the caveats:

1. This page is utterly dependent upon JavaScript to function. I would
normally have made the select visible and hidden it with script when
the page loads, that way it would still be visible if JS is not
available/activated.

However since JS is required to put the selected value into the text
area anyway, there seems no point.

2. The text on the show list button changes, but it may be better to
just have "Show/hide list" and leave it at that. I hate things that
change when I don't expect it to. It may be better to have the button
hidden by default and only shown if JS is enabled. That way users wont
try to click on a button that doesn't do anything.

3. Please excuse my use of styles. I've used some minimal stuff just
for this demo.

I'm done.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top