I have some elements (for example divs with class .label) with radio buttons inside of each. When user clicks this "labels" I programmatically set radio in it as selected. But if I use preventDefault() for click event, the radio didn't selected if user clicked exactly on radio.
Please help me to understand this strange behaviour. I know the solution, I know why preventDefault() on parent element disallows to check radio, but I want to understand, why click event on radio can disallow to set its state programmatically. You will see that click on radio button will say that radio is checked, but it's not.
$(function () {
$('.label').on('click', function(e) {
var $radio = $(this).find(':radio')
console.log('before prevent', `checked=${$radio.prop('checked')}`, `prevented=${e.isDefaultPrevented()}`);
e.preventDefault();
if (!$(this).hasClass('checked')) {
$('.checked').removeClass('checked');
$(this).addClass('checked');
}
$radio.prop('checked', true);
console.log('after prevent', `checked=${$radio.prop('checked')}`, `prevented=${e.isDefaultPrevented()}`);
setTimeout(function () {
console.log('after timeout', `checked=${$radio.prop('checked')}`);
}, 500);
});
$(':radio').on('click', function (e) {
console.log('click', `prevented=${e.isDefaultPrevented()}`);
});
});
.label {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #000;
}
.label.checked {
background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="label">
Label 1 <input type="radio" name="radio" value="1">
</div>
<div class="label">
Label 2 <input type="radio" name="radio" value="2">
</div>
UPDATE. How do I see this situation:
- User clicks on radio
- Firstly event triggered on radio and input setted as checked.
- Then event is bubbling up and triggered on
.label
- Calling preventDefault() sets up an internal
cancelled
flag. div
getting class '.checked' and radio setted as checked again, now programmatically.- Event bubbles on, but nothing happens any more.
- Since the event was cancelled, the default action should not occur and the checkbox is reset to its previous state.
Am I right?