Search code examples
javascriptprototypejs

Multiple events in nested elements


I'm trying to create a web form that contains checkboxes, among other input elements, and I'd like to provide the user with the abilituy to check and uncheck the boxes when clicking on the enveloping div element.

Here's an example of the HTML:

<div class="line">
  <input type="checkbox" />
  <p>No, I don't want more newsletters</p>
</div>

Simple enough. Now, when the user clicks the checkbox, it gets checked/unchecked and the event bubbles up to the div.line element, which may change its background color or something. Now, as I've said, I also want the user to be able to manipulate the checkbox value by clicking on the div. Sounds simple enough; we just add an observer to the div.line element, catch the event and toggle the checkbox value. Well, here's the problem: When you click on the checkbox, it's value is toggled. However, since it resides within the div, you also click on the div, triggering its observer, which in turn toggles the checkbox value once more. So you end up where you started. Two toggles occur.

I've been wrecking my brain over this, trying all different approaches. Custom events, custom element flags... There's simply no way to tell during a single function run whether it was the checkbox that was clicked or if it was the surrounding div element. But there must be a way, I just can't see it.

Does anyone have a clue? I'm using Prototype, by the way.


Solution

  • Use a <label> element with an appropriately directed for attribute:

    <label for="cb"><input type="checkbox" id="cb" /> Click anywhere here</label> 
    

    Demo here.

    The benefit is that the markup becomes semantically agreeable. Note that the for attribute is technically optional if you wrap the target control like this, but IE<7 doesn't support that (but works fine with this sample posted).