...

View Full Version : how to tell if a checkbox's state has changed?



DHTML Kitchen
04-22-2006, 01:19 AM
I want to know if a checkbox has changed. What is the most straightforward approach? I want to "subscribe" to that changed "event" if I can. Change can occur:
* via javascript setter of:
- checked = bCheck;
* via user event:
- click
- keypress (spacebar).

onpropertychange should work for IE, I think.

CheckboxStateChange listener is broken in Mozilla.

CheckboxStateChange ref: http://www.xulplanet.com/references/elemref/ref_EventHandlers.html#attr_CheckboxStateChange

DHTML Kitchen
04-22-2006, 01:47 AM
Oh it seems to work.



<body>
<input type="checkbox" />

<script>

// Works.
var x = {"name" : "garrett"};
x.watch("name", function(p, o, n){alert(n);});
x.name = "sean";


cb = document.getElementsByTagName('input')[0];
cb.watch("checked", function(p, o, n){alert(n);return n;});

</script>

<a href="javascript:void(cb.checked=!cb.checked);">toggle checked</a>
</body>


<p>
An alert pops up when "CHECKED" is changed. But it seems a little slow...
</p>

DHTML Kitchen
04-22-2006, 03:06 AM
Watch works only when checked property is set in javascript.

Watch does not work if user directly clicks the checkbox.

This should be easy...

Kravvitz
04-22-2006, 04:23 AM
Where's the code for watch()?

eak
04-22-2006, 05:38 AM
http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Object:watch

Watch is a built in method of Object. (doesnt work in IE)

Kravvitz
04-22-2006, 05:49 AM
What happens if you do this?

cb = document.getElementsByTagName('input')[0];
cb.checked = cb.checked;
cb.watch("checked", function(p, o, n){alert(n);return n;});

DHTML Kitchen
04-22-2006, 07:13 PM
Method watch only applies to the js property of "checked" when it is changed in js

If you click the checkbox, or trigger it by focusing it and pushing spacebar, then the watch function is not called. This has to do with the way watch is implemented, I believe.

Method watch is like a filter for the setter property. In this case, that property is "checked". When you click the checkbox, that setter is not called. The value for "checked" is updated via internal mechanism of the browser.

See for yourself. CHeck the tescase.
https://bugzilla.mozilla.org/show_bug.cgi?id=335020

Kravvitz
04-22-2006, 11:52 PM
Try this. I haven't tested it in non-Windows browsers.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title></title>
<style type="text/css">

</style>
<script type="text/javascript"><!--
/*
AddEvent Manager (c) 2005 Angus Turnbull http://www.twinhelix.com
Free usage permitted as long as this credit notice remains intact.
*/
if (typeof aeOL == 'undefined')
{
var aeOL = [];
var addEvent = function(o, n, f, l)
{
var d = 'addEventListener', h = 'on' + n, t, a;
if (o[d] && !l) return o[d](n, f, false);
if (!o.aE) { o.aE = aeOL.length || 1; aeOL[o.aE] = { o:o } }
t = aeOL[o.aE][n] || (aeOL[o.aE][n] = []);
for (var i = 0; i < t.length; i++)
for (var j = 0; j < t[i].length; j++)
if (t[i][j] == f) return;
if (o[h] && o[h]._ae)
{
a = t[t.length - 1];
a[a.length] = f;
}
else
{
t[t.length] = o[h] ? [o[h], f] : [f];
o[h] = new Function('e', 'var r = true, i = 0, o = aeOL[' + o.aE + '].o,' +
'a = aeOL[' + o.aE + ']["' + n + '"][' + (t.length - 1) + '];' +
'for (; i < a.length; i++) { ' +
'o._f = a[i]; r = o._f(e||window.event) != false && r; o._f = null;' +
'} return r');
o[h]._ae = 1;
}
};

var removeEvent = function(o, n, f, l)
{
var d = 'removeEventListener', t, a, i, j, s;
if (o[d] && !l) return o[d](n, f, false);
if (!o.aE || !aeOL[o.aE]) return;
t = aeOL[o.aE][n];
i = t.length;
while (i--)
{
a = t[i];
j = a.length;
s = 0;
while (j--)
{
if (a[j] == f) s = 1;
if (s) a[j] = a[j + 1];
}
if (s) { a.length--; break }
}
};

}

function detectChecks(aForm) {
if(!document.getElementsByTagName) return;
if(!(aForm && aForm.tagName && (aForm.tagName.toLowerCase() == 'form'))) {
var forms = document.getElementsByTagName('form');
for(var i=0;i<forms.length;i++) detectChecks(forms[i]);
}
var inputs = aForm.getElementsByTagName('input');
for(var i=0;i<inputs.length;i++) {
if(!inputs[i].type || (inputs[i].type.toLowerCase()!='checkbox')) continue;
if(inputs[i].watch) { // Mozilla Gecko (including Firefox and Netscape 7+)
inputs[i].watch('checked', function (prop,oldval,newval) {
alert(prop + " changed from "+ oldval + " to " + newval);
return newval;
});
} else if(document.defaultCharset && document.getElementsByTagName) { //IE5+
inputs[i].onpropertychange = function() {
if(this.name == event.srcElement.name &&
(!this.id || (this.id == event.srcElement.id)))
if(event.propertyName.toLowerCase() == 'checked')
alert('checked is '+ event.srcElement.checked)
}
}
addEvent(inputs[i],'click',function() { alert(this.checked)});
}
}

window.onload = function() {
if(!document.getElementsByTagName) return;
detectChecks(document.getElementsByTagName('form')[0]);
}
// -->
</script>
</head>
<body>

<p>This works in IE5+/Win, Firefox, and Netscape 7+.
Using watch() crashes Netscape 6.x.
Opera can only detect when the user changes the checked property.</p>

<form name="form1" action="#"
onsubmit="alert('form submitted');return false;"><div>
<label> blue <input type="checkbox" name="checkbox" value="blue"></label><br>
<label> red <input type="checkbox" name="checkbox" value="red"></label><br>
<label> orange <input type="checkbox" name="checkbox" value="orange"></label><br>
<label> yellow <input type="checkbox" name="checkbox" value="yellow"></label><br>
<label> black <input type="checkbox" name="checkbox" value="black"></label><br>
<label> green <input type="checkbox" name="checkbox" value="green"></label><br>
<label> purple <input type="checkbox" name="checkbox" value="purple"></label><br>
<label> <input type="button" value="toggle check of first checkbox via JS"
onclick="var cb=this.form.getElementsByTagName('input')[0];cb.checked=cb.checked?0:1;">
</div></form>

</body>
</html>

joesph
04-23-2006, 11:12 AM
<input type=checkbox onclick=\"my_function()\" name='other[add_value][]'>

var choix = document.getElementsByName('other[add_value][]')

if (choix[add_array_pos].checked == true)

to check an array, where "add_array_pos" is a var, don't know about
what to do if you don't have that, have to experimetn

brothercake
04-23-2006, 08:08 PM
Call me a luddite, but I'd just do it with setInterval :)

DHTML Kitchen
04-24-2006, 08:25 PM
Call me a luddite, but I'd just do it with setInterval :)


Luddite!

DHTML Kitchen
04-24-2006, 08:31 PM
if(el.watch)
el.watch("checked", RowHighlighter.checkModified);
// fires when user clicks.
if(el.addEventListener)
el.addEventListener("CheckboxStateChange", RowHighlighter.checkStateChanged, true);

// For IE.
if("onpropertychange" in el)
el.onpropertychange = RowHighlighter.checkStateChanged;



I'm considering encapsulating this to an adaptor function.

An adaptor that bridges an interceptor (watch is an interceptor) to act like an observer (event listener) just feels wrong.

Polling is looking a little less ugly. A few more drinks...



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum