Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clicking on button label doesn't trigger input click in some scenarios

I am using jquery ui buttonset for some radio buttons. As I understand it, jquery ui makes the label look like a button, while the actual radio itself is underneath, hidden. And when a user clicks on the label, the click is propagated to the input underneath.

I am trying to trigger an event on the radio button set on "change". Most of the time, this works properly. The label is clicked, and the radio is changed underneath and the event fires. However, there are a couple of cases where the label click happens (which causes the button to look like it is currently selected), but the click/change does not propagate to the radio input underneath. This makes it look like a certain option/radio is selected when it really isn't.

Two of these scenarios are:

  1. In chrome, when you "select" the text of the label on the button. The button looks selected, but underneath the radio has not been clicked/changed.
  2. In IE, when user right-clicks to open a custom contextMenu, then clicks off the menu without choosing anything in the menu, and then clicks on the button twice. Again, the button looks selected, but underneath the radio has not been clicked/changed.

My solution is to watch for a click event on the label, and when that happens, check to see if the radio is checked underneath, and if not then check it and trigger the event I wanted triggered on change. Basically, to always force the propagation of the click on the label to the input. This works in both of the scenarios I mention above.

However, I am wondering if there is a better/cleaner way to solve this problem.

Original code:

<div class="view-original-data nav-2nd-line">
    <input type="radio" id="view_current" name="view_original_data_options" value="current" checked="checked">
    <label for="view_current">Current Data</label>
    <input type="radio" id="view_original" name="view_original_data_options" value="original">
    <label for="view_original">Original Data</label>
</div>

Script:

$viewOriginalDataButtons = $(".view-original-data")
        .buttonset()
        .on("change", my.handleOriginalDataOptionsClick);

Fix that is working for me:

$viewOriginalDataButtons = $(".view-original-data")
        .buttonset();
$(".view-original-data label")
        .on("click", function () {
            var labelId = $(this).attr('for'),
                    $buttonClicked = $('#' + labelId);
            if (!$buttonClicked.prop('checked')) {
                $buttonClicked.prop('checked', true);
                my.handleOriginalDataOptionsClick($buttonClicked);
            }
        });
like image 557
KellyS Avatar asked Nov 08 '22 20:11

KellyS


1 Answers

Wrap your input with label and that will solve your problem.

<div class="view-original-data nav-2nd-line">
<!-- Like This one below-->
    <label for="view_current"><input type="radio" id="view_current" name="view_original_data_options" value="current" checked="checked">
    Current Data</label>        
</div>

Update: And why this work? Lets take a look

The "label" element does not render as anything special for the user. However, it provides a usability improvement for mouse users, because if the user clicks on the text within the "label" element, it toggles the control.


Edit after comment: There was an issue in jquery forum and solution was refresh method for that button set. You can use that like:

$("span.that_contains_your_radio_buttons").buttonset("refresh");

As documentation says

Refreshes the visual state of the button. Useful for updating button state after the native element's checked or disabled state is changed programmatically.

like image 191
Atilla Arda Açıkgöz Avatar answered Nov 26 '22 23:11

Atilla Arda Açıkgöz