Search code examples
jqueryradio-buttonlabelhidevisible

I've searched through many posts about using jquery :visible, looking to see if anyone has had conflicts when there's a <label for=""> involved


I am using jquery to show/hide more info when a user selects a radio option. It's a simple concept - when the user clicks within the < dt > tag (i.e., they click either the < input > or < label >) the < dd > slides and stays open to display more information. Clicking within the < dt > tag again closes the < dd >.

I've successfully used this show/hide script in the past, but never with the inclusion of input or label tags. By adding a label with the for= parameter, I get issues:

If you click the radio , the slide opens fine and remains open, but click the label area and the slide opens and immediately bounces closed. In trying to debug, I found if i change or remove the for= to not match the correct id of the radio button (e.g., < input type="radio" id="option01" > < label for="" >), the slide will no longer bounce open to closed, but alas, then I'd be sacrificing accessibility by removing the for=.

Any thoughts on keeping this structure, or close to it, and not dealing with the bounce close effect?

$(document).ready(function() {
   $('.serviceOption').find('dd').hide().end().find('dt').click(function() {
    var moreInfo = $(this).next();
    if (moreInfo.is(':visible')) {
        moreInfo.slideUp();
    } else {
        moreInfo.slideDown('slow');
    }
   });
});

<dl class="serviceOption">  
    <dt>
        <input type="radio" name="serviceOptions" id="option01" value="value01">
        <label for="option01">Option 1</label>
    </dt>  
    <dd>Show more information on Option 1</dd>
    <dt>
        <input type="radio" name="serviceOptions" id="option02" value="value02">
        <label for="option02">Option 2</label>
    </dt>
    <dd>Show more information on Option 2</dd>
</dl>

Here's an example jsFiddle....

http://jsfiddle.net/8JjvT/

Clicking the radio buttons opens and closes the dd correctly. Try clicking the labels to see the problem. It opens and closes immediately.


Solution

  • Ok, I stand corrected: apparently, labels with for= do have issues with click events!

    See this answer: jQuery Click fires twice when clicking on label

    Now, taking that into account, we have to make a decision... the only way I could get it to work properly was to bind the click event to the input field, not the dt.

    Here's my Fiddle: http://jsfiddle.net/mori57/X9pNY/

    // get all the input items from the dt's
    var terms = $(".serviceOption dt input");
    // attach a click handler, pass in the event
    terms.click(function (evt) {
        // store the clicked item's closest dt
        var clickedDT = $(this).closest("dt");
        // if there are visible dd's
        if ($("dd:visible").length > 0) {
            // hide them
            $("dd:visible").slideUp(400, function () {
                // May not need to put this inside the callback, 
                // now that I know it was label's fault
                $(clickedDT).next("dd").slideDown();
            });
        } else {
            // otherwise, just show the nearest dd
            $(clickedDT).next("dd").slideDown();
        }
    });