MindRetrieve Blog

MindRetrieve - an open source desktop search tool for your personal web

Tuesday, November 15, 2005

HTML 3-state checkbox

I have been experimenting with a 3-state checkbox GUI. When we edit the tags of multiple items, there would be some tags that is only used in some items. Just and on and off setting is not enough. We also need a "grey" state to mean leave the tag untouched rather than turning everything on or off.

Since HTML form does not support 3-state checkbox, I have experimented with various simulations using Javascript and CSS. While the widget work resaonble well, I find the "grey" state rather unintuitive. It is obvious what on or off will do. You have to stop to think what grey's action would be.

So I have decided against using 3-state checkbox after all and stick to simple widgets. I think the user in this case would have a strong intent to make properties common among all items. If they leave the checkbox untouched, the tag setting will be unchanged. Otherwise it will be on or off for all.







I have posted one version of the working HTML code here in case if there is any interest. It is tested in Firefox and Opera. Need some simple change to make it work in IE.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/html4/loose.dtd">
<html>
<head>
<style>
#tagControl {
line-height:200%;
}

#tagControl span {
padding-left: 0.3em;
padding-right: 0.5em;
padding-top: 0.3ex;
padding-bottom: 0.3ex;
border: thin outset #777;
font-weight: bold;
color: #000;
}

#tagControl .tagSelect {
}

#tagControl .tagUnchange {
color: #777;
}

#tagControl .tagDelete {
color: #777;
text-decoration: line-through;
}

#tagControl .tagSelectPressed {
color: #fff;
background-color: #777;
border: thin inset #707;
}

#tagControl .tagUnchangePressed {
color: #fff;
background-color: #777;
border: thin inset #707;
}

#tagControl .tagDeletePressed {
color: #fff;
background-color: #777;
border: thin inset #707;
}
</style>

<script>

function toggleTagSelect(e) {
p = this.parentNode
var cb = this;
if (p.className == 'tagSelect') {
p.className = 'tagDelete';
cb.checked = false;
}
else if (p.className == 'tagDelete') {
p.className = 'tagUnchange';
cb.checked = true;
}
else if (p.className == 'tagUnchange') {
p.className = 'tagSelect';
cb.checked = true;
}
}

function onload(e) {
// attach event handlers
var tc = document.getElementById('tagControl');
var elems = tc.getElementsByTagName('input');
for (var i=0; i < elems.length; i++) {
var elem = elems[i];
elem.addEventListener('click', toggleTagSelect, false);
}
}

window.addEventListener('load', onload, false);
</script>
</head>

<body>
<table>
<tr>
<td>Tags</td>
<td>
<div id='tagControl'>
<span class='tagSelect' node='rep:tag'>
<input type='checkbox' />
<a node='rep:tag'>
Gas
</a>
</span>
 
<span class='tagUnchange' node='rep:tag'>
<input type='checkbox' />
<a node='rep:tag'>
Food
</a>
</span>
 
<span class='tagDelete' node='rep:tag'>
<input type='checkbox' />
<a node='rep:tag'>
Lodging
</a>
</span>
 
</div>
</td>
</tr>
</table>

</body>
</html>

0 Comments:

Post a Comment

<< Home