radio button checked property not setting when preventDefault is also used - javascript

The problem I am having is that the radio buttons in my scenario are not being selected when they are clicked. I have created a JSFiddle to show the code and the issue.
For whatever reason, I have an entire area that is surrounded in an element.
<a href="/link">
//some stuff
<div class="protected">
<input type="radio" name="b1" value="1" /> Button 1
<input type="radio" name="b1" value="2" /> Button 2
</div>
//some stuff
</a>
There is a small section within this tag that needs to be protected from the default behaviour of the link. This section contains some radio inputs which need to be selectable.
The way I currently have it, I am protecting the "protected" section with an event listener and:
$('.protected').off('click').on('click', function (e) {
e.preventDefault();
});
I also have an event listener on the radio buttons so that I can perform the change of property when they are clicked.
$('.protected > :radio').off('click').on('click', function (e) {
$(this).siblings(':radio').removeAttr('checked');
$(this).attr('checked', 'checked');
});
Unfortunately, this is setting the checked attribute in the dom however the radio button is not being filled in on the screen for the user.
Any help would be greatly appreciated.

You need to add stopPropagation()
$('.protected > :radio').off('click').on('click', function (e) {
e.stopPropagation();
//$(this).siblings(':radio').removeAttr('checked');
//$(this).attr('checked', 'checked');
});
Also, make sure to comment out
$(this).siblings(':radio').removeAttr('checked');
$(this).attr('checked', 'checked');
You don't need them as the browser handles this for you.
DEMO
What was happening is, since you had preventDefault in the container click handler, the nested click event was propagating to that click handler and was preventing the radio button from being set.

Related

Javascript And Query

I am new to Javascript and trying to add a and Query to a js file.
I have added a checkbox this is required to be checked for the submit button to show.
In the original there was already one checkbox with the js query but I have added a second. How do I make the js only allow the button to be clicked when both are checked?
The current code for the js is
jQuery('.check_policy').on('click', function(){
if(jQuery('#policycheck') .is(':checked')){
jQuery("#listingsubmitBTN").prop('disabled',false);
jQuery("#listingsubmitBTN").removeClass('dissablebutton');
}
else{
jQuery("#listingsubmitBTN").prop('disabled',true);
jQuery("#listingsubmitBTN").addClass('dissablebutton');
}
});
The second check box I have added is called policycheck_2
Thanks in advance for any help. I think this could be one of many js questions
Mark
jQuery('.check_policy').on('click', function(){
if(jQuery('#policycheck').is(':checked') && jQuery('#policycheck_2').is(':checked')){
jQuery("#listingsubmitBTN").prop('disabled',false).removeClass('dissablebutton');
}
else{
jQuery("#listingsubmitBTN").prop('disabled',true).addClass('dissablebutton');
}
});
Edit: Just add an AND (&&) operator with the same syntax with the new ID as the first one in the if statement.
I'll also shortened the rest a little bit, looks nicer. :-)
Separate the responsibilities.
Bind the click event to the checkboxes. The handler only has to trigger the event on the specific button.
Bind a custom event to your button which validates the checked boxes.
Use this condition to disable or enable:
$('.check_policy').length !== $('.check_policy:checked').length
$('.check_policy').on('click', function() {
// Here we trigger the custom event.
$('#listingsubmitBTN').trigger('validatechecked');
// Now this handler only trigger events to specific elements and not
// everything mixed here.
});
$('#listingsubmitBTN').on('validatechecked', function() {
$(this).prop('disabled', $('.check_policy').length !== $('.check_policy:checked').length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class='check_policy' type='checkbox'>Check policy#1
<p>
<input class='check_policy' type='checkbox'>Check policy#2
<p>
<input type='button' id='listingsubmitBTN' value="Click me!" disabled>
Your main issue is that your if statement is not checking if both checkboxes are checked - it still only checks to see if #policycheck is checked to determine the disabled status of the button. A simple fix would be to add the jQuery("#policycheck_2").is(":checked") to your if statement, and your code will work - however, you can leverage using an expression in the prop setter function, as well as the toggleClass function to simplify/shorten/clean-up your code a bit.
Here's an example of what that would look like:
jQuery('.check_policy').on('click', function() {
var bothChecked = jQuery("#policycheck").is(":checked") && jQuery("#policycheck_2").is(":checked");
jQuery("#listingsubmitBTN").prop("disabled", !bothChecked).toggleClass("dissablebutton", !bothChecked);
console.log("button", bothChecked ? "enabled" : "disabled");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="policycheck" />
<input type="checkbox" id="policycheck_2" />
<button class="check_policy">Check Policy</button>

jQuery not capturing click event following trigger call on HTML radio button

I have a very strange issue with jQuery where I am triggering a click on a radio button but it is not firing completely and is not being captured by an on click function, however a similar call to jQuery trigger is being captured.
In the following jQuery I am selecting a <div> and using find to search for the suitable content.
var prev_chosen_d_option = $('#d_options_table .d_option_row[data-option-id="' + d_option_for_jq + '"]');
// this works, and the on click is captured
prev_chosen_d_option.find('.hover_target').trigger("click", true);
// this selects the radio button, but DOES NOT fire the on click function seen below
prev_chosen_d_option.find('#d_standard_use_b_as_s_no').trigger("click", true);
These are my radio buttons:
<input type="radio" value="yes" id="d_standard_use_b_as_s_yes" name="d_standard_use_b_as_s">
<input type="radio" value="no" id="d_standard_use_b_as_s_no" name="d_standard_use_b_as_s">
$("#d_options_table .d_option_row .hover_target").on("click", function(e, isFirstLoad) {
// it comes in here fine!
});
$('input[name=d_standard_use_b_as_s], input[name=d_next_day_use_b_as_s], #del_standard_use_b_as_s_no').on("click", function(e, isFirstLoad) {
// it DOESN'T come in here
});
I can't see how jQuery is able to select the radio button and successfully check it, but the on method doesn't pick it up as a click...especially when I have a very similar setup running in close proximity in the code.
I know for sure that the radio buttons are within the selector as I can dump it out to the console with a console.log. Interestingly, when I dump out the events attached to it to the console I get undefined from this after the trigger:
console.log(prev_chosen_d_option.find("#_standard_use_b_as_s_no").data('events'));
(I am using jQuery 1.7.2 and testing in FF).
Instead of
$('input[name=del_standard_use_b_as_s], input[name=del_next_day_use_b_as_s], #del_standard_use_b_as_s_no').on('click', function(e) {
//
});
Try :
$(document).on('click', 'input[name=del_standard_use_b_as_s], input[name=del_next_day_use_b_as_s], #del_standard_use_b_as_s_no', function(e) {
//
});
The reason for this not working was simply I had the click handler below where I was actually triggering the click in the code.

Determining when a radio button selection has changed with YUI3

I am using YUI3 and Internet Explorer 8 and Firefox. I am trying to determine when a radio button has changed selection.
My HTML:
<div id="test">
<input name="test1" value="a" type="radio">
<input name="test1" value="b" type="radio">
<input name="test1" value="c" type="radio">
</div>
My JavaScript:
YUI().use('event', 'node', function (Y) {
Y.one('input[name=test1]').on('change', function (e) {
alert('changed');
});
});
This doesn't work because the page loads nothing is selected in the radio button group. When I select the first item nothing happens, no alert pops up. When I click the second button then it pops up. How do I determine when a radio button selection has changed?
Also how do I get the value of the selected radio button, I think there are IE issues? This bombs out:
var value = Y.one('input[name=test1]:checked').get('value');
alert(value);
And this bring back nothing:
var value = Y.all('input[name=test1]:checked').get('value');
alert(value);
You can use event delegation to listen to the "click" event. If you don't know what event delegation is, check out this short intro. The change event has issues in older browsers so stick to the click event. All you need to do is get the parent element with Y.one and set up a delegation listener:
YUI().use('node', function (Y) {
Y.one('#test').delegate('click', function (e) {
alert(e.target.get('value'));
}, 'input[type=radio]');
});

jQuery - Checkbox not being checked

I'm using checkboxes to toggle the enabled and disabled state of some multi-lists on a registration form. The checkbox is labeled with the category, and the multi-list contains the items that belong to that category.
I'm using jQuery 1.7.2.
$('#sch_cat_hockeyschools').toggle(function(ev) {
ev.stopPropagation();
$("#type_select_hockeyschools").prop("disabled", false);
$("#type_select_hockeyschools").removeProp("disabled", "disabled");
$("#sch_cat_hockeyschools").prop("checked", true);
$("#sch_cat_hockeyschools").prop("checked", "checked");
}, function(ev) {
ev.stopPropagation();
$("#type_select_hockeyschools option:selected").removeAttr("selected");
$("#type_select_hockeyschools").prop("disabled", true);
$("#type_select_hockeyschools").prop("disabled", "disabled");
$("#sch_cat_hockeyschools").prop("checked", false);
$("#sch_cat_hockeyschools").removeProp("checked");
});
Sample of corresponding checkbox HTML:
<input class="catmark" type="checkbox" name="sch_categories[]" id="sch_cat_hockeyschools" value="1" />General Hockey Schools
<input class="catmark" type="checkbox" name="sch_categories[]" id="sch_cat_springhockey" value="2" />Spring Hockey
The problem is that the upon clicking the checkbox, the checkbox does not become ticked or checked; it immediately returns to an unchecked state, which I thought the stopPropagation() function would help with. Apparently not. The multi-lists get enabled and disabled as expected, but the checkbox doesn't get ticked.
The result of this problem is that when the form is submitted, the array containing the selected categories is empty; thus, because at least one checked category is a required field in the form, the PHP script that processes the form throws one of my errors which tells me a required field was left blank.
Any ideas on how to make sure that the checkbox actually gets checked, and by extension, POSTS actual data to the processing script?
Thanks guys.
The problem is the use of toggle -- per the documentation:
The implementation also calls .preventDefault() on the event, so links
will not be followed and buttons will not be clicked if .toggle() has
been called on the element.
toggle itself is calling preventDefault, which is stopping the default behavior of the event, checking/unchecking the box.
Rather than toggle, use bind or on (see edit note below) to add a listener for the change event, in which you can examine the state:
$('#sch_cat_hockeyschools').on('change', function () {
if (this.checked) {
// do stuff for a checked box
console.log('check is on');
} else {
// do stuff for an unchecked box
console.log('check is off');
}
});
Try it out at jsFiddle.
EDIT
Please note, this code shows use of the on method, whereas the jsFiddle example uses bind. As pointed out by Sam Sehnert, on is the preferred method for attaching events with > jQuery 1.7. If you are using an older version of jQuery, use bind as in the jsFiddle example.
Documentation
jQuery.toggle
jQuery.bind
jQuery.on

how to prevent checkbox check when clicking on link inside label

I have a link inside a label. The problem is, when user clicks 'back' after having read the terms, the checkbox is unchecked, because when they clicked on the link they also unchecked the box at the same time, since the link is inside a label.
<input type="checkbox" id="terms" name="terms" checked="checked" />
<label for="terms">I agree to be bound by the Terms</label>
How can I prevent the checkbox from being checked when link is clicked? Tried doing event.preventDefault() on label click, but that doesn't prevent checkbox from being checked/unchecked.
I could just take out the link from inside a label (which means more CSS styling). But now I'm curious whether the above is possible.
You can cancel the click event by routing it through an onclick event.
The "return false;" part will prevent the click event from moving up to the label.
<input type="checkbox" id="terms" name="terms" checked="checked" />
<label for="terms">I agree to be bound by the Terms</label>
Also good practice to allow opening links with target="_blank" in new tabs.
/*
Fix links inside of labels.
*/
$( 'label a[href]' ).click( function ( e ) {
e.preventDefault();
if ( this.getAttribute( 'target' ) === '_blank' ) {
window.open( this.href, '_blank' );
}
else {
window.location = this.href;
}
});
Why not move the link outside the label?
<label for="terms">I agree to be bound by the</label> Terms
Just add the 'for' attibute and it will prevent from unwanting bubbling
You could have the link open up in a new window so that the page doesn't change.
If you don't want to do that you could check to see if the link has been visited and then automatically check the box.
I have a similar situation, but the link actually opens a new window when clicked. This doesn't check/uncheck the box. I believe it is because the click doesn't bubble up through the link to the label.
So, to extend this, if you want the link to open in the same page, you could make it open using a click handler and preventing the click on the link from bubbling, like so:
$('label a').click(function(ev) { ev.preventDefault(); window.location.href = $(this).attr('href'); }
(It's untested and not the nicest use of JS, but it should solve your issue)
I agree the best way (for usability and ease) would be to open the terms in a new window, but if you wish to open it in the same one you can use this little function:
function stopLabel(e) {
e.preventDefault();
window.location= '/terms';
}
You could also put them straight into your onclick but this is a bit nicer imo.
You would have to pass the event to the function too:
<label for="terms">I agree to be bound by the Terms</label>
If you decide to open it in a new window you can just change the window.location to window.open
The link should be outside the label and not a part of it since clicking on it will trigger two action (opening the link and checking the checkbox).
The user is expecting to trigger only one action,
if the link looks like a link he would expect to be taken to the links target,
or if the text is related to the checkbox the user will expect it to check the checkbox.
If you are ok with opening the link in a new tab (and I think it is better, because maybe the user has already filled some data on the page) then this can be handled even without js
<input type="checkbox" id="agreed" />
<label for="agreed">
I agree with Terms of use and Privacy Policy
</label>
here is js fiddle example
http://jsfiddle.net/davo3/zkcv3L3d/

Categories