Detecting status change in a checkbox

Discussion in 'Javascript' started by waleed, Sep 29, 2008.

  1. waleed

    waleed Guest

    I'm not really good with javascript, basically what I'm trying to do
    is that I want to be able to handle when the status of a checkbox is
    changed (i.e. checked or unchecked), I see everybody is using onclick
    but I wonder if this is the correct approach, what if a user changes
    the status of the checkbox using the keyboard, will onclick be
    triggered? I know I might sound a little picky here but I believe
    those people who created DHTML must've thought about this, right?

    Sorry if I posted the question in the wrong group, I couldn't find a
    good group for DHTML, I assume many people post questions about DHTML
    here as javascript and DHTML are very related, anyway a post in the
    wrong group is still better than all this spam I see everywhere here!
    waleed, Sep 29, 2008
    #1
    1. Advertising

  2. waleed

    waleed Guest

    Never mind guys, I just realized that onclick is also triggered when
    the user checks/unchecks the checkbox using the keyboard ...
    waleed, Sep 29, 2008
    #2
    1. Advertising

  3. waleed

    Steve Swift Guest

    waleed wrote:
    > I'm not really good with javascript, basically what I'm trying to do
    > is that I want to be able to handle when the status of a checkbox is
    > changed (i.e. checked or unchecked), I see everybody is using onclick
    > but I wonder if this is the correct approach, what if a user changes
    > the status of the checkbox using the keyboard, will onclick be
    > triggered?


    I think that onChange is what you want. I was tinkering with some
    onChange code for RADIO buttons recently, and discovered that onChange
    seems to trigger for radio buttons only when they change from unchecked
    to checked. There is some sense in this, otherwise you'd often get two
    events each time a button was changed (the other one coming from the
    button which got unchecked).

    --
    Steve Swift
    http://www.swiftys.org.uk/swifty.html
    http://www.ringers.org.uk
    Steve Swift, Sep 29, 2008
    #3
  4. waleed

    dhtml Guest

    Steve Swift wrote:
    > waleed wrote:
    >> I'm not really good with javascript, basically what I'm trying to do
    >> is that I want to be able to handle when the status of a checkbox is
    >> changed (i.e. checked or unchecked), I see everybody is using onclick
    >> but I wonder if this is the correct approach, what if a user changes
    >> the status of the checkbox using the keyboard, will onclick be
    >> triggered?

    >
    > I think that onChange is what you want. I was tinkering with some
    > onChange code for RADIO buttons recently, and discovered that onChange
    > seems to trigger for radio buttons only when they change from unchecked
    > to checked. There is some sense in this, otherwise you'd often get two
    > events each time a button was changed (the other one coming from the
    > button which got unchecked).
    >


    onchange is "specified" to fire after the element loses focus and it has
    a new value.[1][2]

    However, when the control is checkbox or radio, the |checked| state is
    usually what determines the "onchange" firing.

    But that's only part of the picture.

    When a radio or checkbox |checked| property is set in script, onchange
    won't fire. Even when calling focus() before and blur() after.

    The only way to get onchange to fire is for the user to change it, or to
    dispatch a change event on the target programmatically, using
    initMouseEvent[3][2]. initMouseEvent has the unusual design of 15
    parameter variables. I still haven't memorized the order.

    Mozilla has a checkboxstatechange event[4] for XUL that seems to have
    leaked into HTML. Probably not the most reliable thing to use in
    production apps, and has been filed as a bug[5].

    I can't explain the reasoning behind the HTML and DOM specs ignoring
    "change" for radio and checkbox. I can, however, demonstrate that the
    facts are provable in a very simple demonstration:-

    ========================================================
    <!DOCTYPE html>
    <html>
    <head>
    <title>checkbox onchange firing for programmatic changes</title>
    </head>
    <body>
    <form action="">
    <input type="checkbox" name="a" id="a1">
    <input type="checkbox" name="a" id="a2">
    <input type="checkbox" name="a" id="a3">
    </form>
    <pre id='monitor'> </pre>
    <script type="text/javascript">
    document.onchange = function(e) {
    text.data += '\n' + e.type + ": " +
    e.target.type + "#" + e.target.id;
    };

    var inputs = document.body.getElementsByTagName('input'),
    i = 0,
    text = document.getElementById('monitor').firstChild;

    var timer = setInterval(function() {
    if(!inputs) {
    i = 0;
    clearTimeout(timer);
    }
    var checkbox = inputs;
    checkbox.focus();
    text.data += "\ncheckbox " + checkbox.id + " focused";
    text.data += "\ncheckbox " + checkbox.id + " changed";
    checkbox.checked = true;
    //checkbox.value = i;
    checkbox.blur();
    text.data += "\ncheckbox " + checkbox.id + " blurred\n";
    i++;
    }, 600);


    </script>
    </body>
    </html>

    ========================================================

    Running the example in three browsers (op, ff, saf), the result of
    changing the |checked| property via script will not cause a change event
    to fire. The output looks like:

    | checkbox a1 focused
    | checkbox a1 changed
    | checkbox a1 blurred
    |
    | checkbox a2 focused
    | checkbox a2 changed
    | checkbox a2 blurred
    |
    | checkbox a3 focused
    | checkbox a3 changed
    | checkbox a3 blurred
    |
    | checkbox a1 focused
    | checkbox a1 changed
    | checkbox a1 blurred


    However, change will fire when you, as a user, click the checkbox by
    clicking it with your mouse or activating it with the spacebar when it's
    focused.

    | change: checkbox#a1
    | change: checkbox#a2
    | change: checkbox#a3

    Radio buttons don't fire change when checked programmatically either.
    They only fire change on user action.

    SO, to answer the OP's question, I think you can use a combination of
    polling the event, plus capturing the change event on the object itself.
    If supporting IE is concerned, don't use bubbling. Change doesn't bubble
    in IE[6].

    Garrett

    [1] HTML 4.01
    http://www.w3.org/TR/REC-html40/interact/scripts.html#h-18.2.3
    [2] DOM Events
    http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-htmlevents-h3
    [3] initMouseEvent
    http://developer.mozilla.org/en/DOM/event.initMouseEvent
    [4] checkboxstatechange, XUL Planet
    http://www.xulplanet.com/references/elemref/ref_EventHandlers.html
    [5] Mozilla Bug 335020 "No nice way to watch for checkbox toggle"
    https://bugzilla.mozilla.org/show_bug.cgi?id=335020
    [6] MSDN: onchange Event
    http://msdn.microsoft.com/en-us/library/ms536912(VS.85).aspx
    dhtml, Sep 29, 2008
    #4
  5. waleed

    Bart Lateur Guest

    dhtml wrote:

    >The only way to get onchange to fire is for the user to change it, or to
    >dispatch a change event on the target programmatically, using
    >initMouseEvent[3][2]. initMouseEvent has the unusual design of 15
    >parameter variables. I still haven't memorized the order.


    You can also call the onclick and/or onchange event handlers manually,
    while you're changing the checked status.

    function check(el, bool) {
    el.checked = bool;
    if(el.onclick) el.onclick.call(el);
    if(el.onchange) el.onchange.call(el);
    }

    You can pass extra parameters for the event methods to call(), typically
    it should representing the event that triggered the callback, but most
    onclick/onchange handlers don't even look at it. So, in such a case, you
    don't need it.

    Here's a complete sample:

    <form>
    <label><input type="checkbox" name="test"
    onclick="this.parentNode.style.backgroundColor = this.checked ? 'red' :
    'green'"> check, or not</label><br>
    <label><input type="radio" name="remote" onclick="check(this.form.test,
    true)"> on</label>
    <label><input type="radio" name="remote" onclick="check(this.form.test,
    false)"> off</label>
    </form>
    <script type="text/javascript">
    function check(el, bool) {
    el.checked = bool;
    if(el.onclick) el.onclick.call(el);
    if(el.onchange) el.onchange.call(el);
    }
    </script>

    --
    Bart.
    Bart Lateur, Sep 29, 2008
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. saha
    Replies:
    0
    Views:
    4,040
  2. Shug
    Replies:
    13
    Views:
    890
    Philipp
    Dec 15, 2006
  3. Shug
    Replies:
    13
    Views:
    944
    Philipp
    Dec 15, 2006
  4. harryos
    Replies:
    0
    Views:
    374
    harryos
    Oct 13, 2010
  5. Sven S.

    status info like rc.status

    Sven S., Dec 9, 2008, in forum: Ruby
    Replies:
    2
    Views:
    169
    Sven S.
    Dec 11, 2008
Loading...

Share This Page