counting checkboxes after click using jQuery - javascript

I need to count the number of checkboxes in a form that are 'checked' AFTER being clicked and BEFORE the form is submitted. I have a javascript function that is called when a box is clicked which changes some values in the form dynamically. But it is returning the counts and values which are present at the time the box is clicked.
As my code is now, I have an onClick event handler on a enclosing the checkbox and label:
<div class="part" style="padding-right: 30px" onClick="runThis()">
<input id="checkbox_2" name="dog" type="checkbox" class='topdog' checked='checked' value="2" />
<label for="checkbox_2">Snoopy (Top Dog)</label>
</div>
...
function runThis() {
var dogsSelected = jQuery("input[name='dog']:checked");
var numSelected = dogsSelected.length;
alert("numSelected: " + numSelected);
}
I am sure there is a simple solution or I am approaching this incorrectly.
Any tips/advice are appreciated.

Are there any JavaScript errors? I found that if you take that runThis() function out of $(document).ready it works properly.
You might also consider removing that onClick= attribute in favor of jQuery event handlers:
$("input[name='dog']").on('click',function(e) {
var dogsSelected = $("input[name='dog']:checked");
var numSelected = dogsSelected.length;
alert("numSelected: " + numSelected);
});
http://jsfiddle.net/mblase75/xsWDn/

If so, you should try to change it to react on mouse up, you should get a different result.
You are probably activating the event before the changes has been made to the dom three.
Edit:
nevermind it says onclick triggers in the question. my bad for not reading.
Try changing it to : onmouseup, i guess that should do the trick:
<div class="part" style="padding-right: 30px" onmouseup="runThis()">
<input id="checkbox_2" name="dog" type="checkbox" class='topdog' checked='checked' value="2" />
<label for="checkbox_2">Snoopy (Top Dog)</label>

You can use the 'change' event:
$("input[name='dog']").on('change', runThis);
function runThis() {
var dogsSelected = jQuery("input[name='dog']:checked");
var numSelected = dogsSelected.length;
alert("numSelected: " + numSelected);
}​
http://api.jquery.com/change/

Related

jQuery event for all radiobuttons affected by change of one [duplicate]

Is there an easy way to attach a "deselect" event on a radio button? It seems that the change event only fires when the button is selected.
HTML
<input type="radio" id="one" name="a" />
<input type="radio" id="two" name="a" />
JavaScript
$('#one').change(function() {
if(this.checked) {
// do something when selected
} else { // THIS WILL NEVER HAPPEN
// do something when deselected
}
});​
jsFiddle
​
Why don't you simply create a custom event like, lets say, deselect and let it trigger on all the members of the clicked radio group except the element itself that was clicked? Its way easier to make use of the event handling API that jQuery provides that way.
HTML
<!-- First group of radio buttons -->
<label for="btn_red">Red:</label><input id="btn_red" type="radio" name="radio_btn" />
<label for="btn_blue">Blue:</label><input id="btn_blue" type="radio" name="radio_btn" />
<label for="btn_yellow">Yellow:</label><input id="btn_yellow" type="radio" name="radio_btn" />
<label for="btn_pink">Pink:</label><input id="btn_pink" type="radio" name="radio_btn" />
<hr />
<!-- Second group of radio buttons -->
<label for="btn_red_group2">Red 2:</label><input id="btn_red_group2" type="radio" name="radio_btn_group2" />
<label for="btn_blue_group2">Blue 2:</label><input id="btn_blue_group2" type="radio" name="radio_btn_group2" />
<label for="btn_yellow_group2">Yellow 2:</label><input id="btn_yellow_group2" type="radio" name="radio_btn_group2" />
<label for="btn_pink_group2">Pink 2:</label><input id="btn_pink_group2" type="radio" name="radio_btn_group2" />
jQuery
// Attaching click event handlers to all radio buttons...
$('input[type="radio"]').bind('click', function(){
// Processing only those that match the name attribute of the currently clicked button...
$('input[name="' + $(this).attr('name') + '"]').not($(this)).trigger('deselect'); // Every member of the current radio group except the clicked one...
});
$('input[type="radio"]').bind('deselect', function(){
console.log($(this));
})
​Deselection events will trigger only among members of the same radio group (elements that have the same name attribute).
jsFiddle solution
EDIT: In order to account for all possible placements of the attached label tag (wrapping the radio element or being attached through an id selector) it is perhaps better to use onchange event to trigger the handlers. Thanks to Faust for pointing that out.
$('input[type="radio"]').on('change', function(){
// ...
}
You can create a custom "deselect" event relatively painlessly, but as you've already discovered the standard change event is only triggered on the newly checked radio button, not on the previously checked one that has just been unchecked.
If you'd like to be able to say something like:
$("#one").on("deselect", function() {
alert("Radio button one was just deselected");
});
Then run something like the following function from your document ready handler (or put the code directly in your document ready handler):
function setupDeselectEvent() {
var selected = {};
$('input[type="radio"]').on('click', function() {
if (this.name in selected && this != selected[this.name])
$(selected[this.name]).trigger("deselect");
selected[this.name] = this;
}).filter(':checked').each(function() {
selected[this.name] = this;
});
}
Working demo: http://jsfiddle.net/s7f9s/2
What this does is puts a click handler on all the radios on the page (this doesn't stop you adding your own click event handlers to the same radios) that will check if there was a previously selected radio in the same group (i.e., with the same name) and if so trigger a "deselect" event on that radio. Then it saves the just-clicked one as the current one. The "deselect" event is not triggered if you click the already checked radio or if there was no previously checked one. The .filter().each() bit at the end is to make note of which radios are already selected. (If you need to cater for more than one form on the same page having independent radio groups of the same name then update the function above accordingly.)
I found that the simplest way to do this without putting in a new framework to create a deselected event, is to make changing any radio button trigger an update event on all of the radio buttons in its group and then define the behavior you want in the update event.
The downside is that the code in the deselection branch will run even if the radio button was not previously selected. If all you're doing is simple showing, hiding, or disabling UI elements, that shouldn't matter much.
To use your example:
buttons = $('input[name="a"]');
buttons.change(function() {
buttons.trigger('update:groupA');
}).bind('update:groupA', function(){
if(this.checked) {
//Do your checked things
} else {
//Do your unchecked things. Gets called whenever any other button is selected, so don't toggle or do heavy computation in here.
}
});​
I think you need to add the change function on the input level, rather than on each radio button.
Try this:
$("input[name='a']").change(function() {
$("input[name='a']").each(function(){
if(this.checked) {
// do something when selected
} else {
// do something when deselected
}
});
});​
I think this could be happening because the focus event triggers before the change event so the next radio you click will be focused before the previous checked radio triggers a change event. Don't quote me on this though...
You could do it like this:
var isChecked = function(id) { alert(id + ': ' + $('#' + id).is(':checked')) }
$('input[name="a"]').change(function(){ isChecked('one') })
Demo: http://jsfiddle.net/elclanrs/cD5ww/
You can trigger the 'change' event yourself. It's a bit tricky to avoid radio buttons infinitely triggering 'change' event on each other, but it can be done like this:
$('input[type="radio"]').each(function() {
var name = $(this).attr('name');
var that = this;
$('input[name="'+name+'"][type="radio"]').not(that)
.on('change', function(e, alreadyTriggered) {
if(!alreadyTriggered || alreadyTriggered.indexOf(this) == -1) {
if(!alreadyTriggered) {
alreadyTriggered = [that];
}
alreadyTriggered.push(this);
$(that).trigger('change', [alreadyTriggered]);
}
});
});
Here's the demo of the above code at work.
I found a workaround for my specific case that might help. This works when the "deselect" event can be applied to all radio buttons that aren't selected.
I wanted to:
add a class to the element when the radiobutton was selected, and
remove that class when the button was "deselected".
I happened to find this question, because I had the same problem:
$('input:radio').on('change', function() {
if( $(this).is(':checked') ) {
$(this).addClass('my-class-for-selected-buttons')
} else { // THIS WILL NEVER HAPPEN
$(this).removeClass('my-class-for-selected-buttons')
}
});​
But, in my case, the solution was pretty much easier, because I can try to remove the class from all the radio-buttons pretty simply with jQuery, and then add the class to the selected one:
$('input:radio').on('change', function() {
$('input:radio').removeClass('my-class-for-selected-buttons') // Here!
if( $(this).is(':checked') ) {
$(this).addClass('my-class-for-selected-buttons')
}
});​
With this simple tweak, I didn't need to find a way to trigger the "deselect" event.
So, if in your case you can apply the event to all the radio buttons that aren't selected, and not only to the one that's just been "deselected", you can use this measure!
Note: I'm using the most recent version of jquery: version 3.4.1. But this should work for older versions as well.
The major challenge here is that the change event is only triggered for the radio button that was checked. The code below confirms this.
$("input[name^='account']").change(function() {
console.log($(this).prop('id') + " was checked");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<form action='#'>
<input id='john' type='radio' name='account[]' value=''><label for='john'>John</label><br>
<input id='jane' type='radio' name='account[]' value=''><label for='jane'>Jane</label><br>
<input id='jeff' type='radio' name='account[]' value=''><label for='jeff'>Jeff</label><br>
<input id='jude' type='radio' name='account[]' value=''><label for='jude'>Jude</label><br>
<input type='text' name='amount' value=''><br>
<input type='submit' value='submit'>
</form>
My Solution: Handle everything inside the change event handler in 3 simple steps:
handle the changes for the currently checked radio button.
attach custom event and handler to all other radio buttons in the same group.
immediately trigger this custom event.
No need to play around with click events here. simple!
var radioBtns = $("input[name^='account']");
radioBtns.change(function() {
// 1. handle changes for the currently checked radio button.
console.log($(this).prop('id') + " was checked");
// 2. attach custom event and handler to all other radio buttons in the same group.
radioBtns.not(':checked').off('deselect').on('deselect', function() {
$(this).each(function(i, e) {
console.log($(e).prop('id') + " was not checked");
});
}).trigger('deselect'); // 3. immediately trigger this custom event.
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<form action='#'>
<input id='john' type='radio' name='account[]' value=''><label for='john'>John</label><br>
<input id='jane' type='radio' name='account[]' value=''><label for='jane'>Jane</label><br>
<input id='jeff' type='radio' name='account[]' value=''><label for='jeff'>Jeff</label><br>
<input id='jude' type='radio' name='account[]' value=''><label for='jude'>Jude</label><br>
<input type='text' name='amount' value=''><br>
<input type='submit' value='submit'>
</form>
I played a bit with the ids.
That is probably an inefficient solution to be fair.
<input type="radio" id="radio-1" name="a" value="initial 1"/>
<input type="radio" id="radio-2" name="a" value="initial 2"/>
let id;
$('input[id*="radio-"]').on('click', (function() {
if (this.id != id && this.checked) {
id = this.id;
this.checked = true;
console.log('selected');
} else if (this.id == id && this.checked) {
id = undefined;
this.checked = false;
console.log('deselected');
}
}));
JSFiddle
hows this for ya?
http://jsfiddle.net/WZND9/6/
$('input').change(function() {
if ($('#one').is(':checked')) {
alert('checked');
} else {
alert('not checked');
}
});

Jquery how to use variable as identifier for .change() function?

right now I am a beginner in Javascript/Jquery.
I want to create a dynamic code, so that it will work when there comes some new features to the website without need to edit code.
Now i just read in some posts how to use a variable as identifier for id, but it is not working for me. So below is an example:
var category;
$('#mainCategory').change(function (event) {
checkboxID = event.target.id;
category="category"+checkboxID;
...some code...
});
$("#"+category).change(function (event) {
$('#category'+checkboxID+' :input').attr('class','' );
console.log("var: "+category);
});
So the function mainCategory always runs before the other one and category got written correct in the 2nd function, when i am using the whole expression instead of using a variable.
I hope you can help me.
the part of html code:
<form method="post" action="../php/saveTraining.php">
<section id="mainCategory" class="hidden">
<label><input type="checkbox" id="Krafttraining">Krafttraining</label>
<label><input type="checkbox" id="Joggen">Joggen</label>
</section>
<section id="categoryKrafttraining" class="hidden">
<label><input type="checkbox">Kurzhantel</label>
<label><input type="checkbox">Bankdrücken</label>
<label class="hidden"><input type="number" id="saetze">Sätze</label>
<label class="hidden"><input type="number" id="wiederholungen">Wiederholungen</label>
</section>
<input type="hidden" id="saveTraining" name="sent" value="save" class="hidden"/>
</form>
So what actually happens is that when checking a checkbox of mainCategory the checkboxes of the second section appearing.
But when I check a checkbox of the second section nothing happens.
I thought I had the solution before but I see I was wrong. I believe this should work, where you re-add the listener as the value for the var category change:
var category;
$('#mainCategory input[type="checkbox"]').change(function (event) {
checkboxID = event.target.id;
category="category"+checkboxID;
$('#' + category).find('input[type="checkbox"]').off("change").on("change", function (event) {
$('#category'+checkboxID+' :input').attr('class','' );
console.log("var: "+category);
});
});
You need to re-add the listener because new elements will be targeted as var category changes.

jquery mobile set selected value of a radio button group

I have a radio button group like this:
<div data-role="fieldcontainer">
<fieldset data-role="controlgroup" data-type="horizontal" name="optRestriction" id="optRestriction">
<legend>Restriction</legend>
<input type="radio" name="chkRestriction" id="chkRed" value="R" class="custom" />
<label for="chkRed">Red</label>
<input type="radio" name="chkRestriction" id="chkYello" value="Y" class="custom" />
<label for="chkYello">Yellow</label>
<input type="radio" name="chkRestriction" id="chkGreen" value="G" class="custom" />
<label for="chkGreen">
I am trying to set the selected value after retrieving values from the serve API.
I have tried various ways like below:
$("input[name=chkRestriction][value=" + data.rows[0].restrictionCd + "]").prop('checked', true).trigger('change');
$("input[type='radio']:eq(" + data.rows[0].restrictionCd + ")").attr("checked", "checked");
$("input[type='radio']").checkboxradio("refresh");
$("input[name=chkRestriction][value=" + data.rows[0].restrictionCd + "]").prop('checked', true).trigger('change');
$('[name="chkRestriction"]').val([ data.rows[0].restrictionCd ]);
But none seem to work. A demo fiddle is here
Appreciate any suggestions in advance.
Set attribute "checked" and call refresh.
$('input:radio[name="chkRestriction"]').filter('[value="R"]').attr("checked",true).checkboxradio("refresh");
Jsfiddle - https://jsfiddle.net/of7uvbwh/3/
Set/unset the value of each radio button in a loop like this this:
var valToSet = myVal; // myVal is value to set from API
$('#optRestiction input').each(function(){
var $this = $(this)
if($this.val() == valToSet) {
$this.prop('checked', true);
}
else {
$this.prop('checked', false);
}
});
The 'changed' event fires when one of your inputs changes state. Triggering it will accomplish nothing unless you have defined a handler for the 'changed' event for that input.
Try this.
$('input:radio[name="chkRestriction"]').filter('[value="R"]').attr("checked",true).checkboxradio().checkboxradio("refresh");

jQuery click event on radio button doesn't get fired

I've got the following code to trigger a click event on some radio buttons! but it doesn't get fired! can any one help me with this!
CODE :
$("#inline_content input[name='type']").click(function(){
if($('input:radio[name=type]:checked').val() == "walk_in"){
$('#select-table > .roomNumber').attr('enabled',false);
}
});
RADIO BUTTONS
<form class="type">
<input type="radio" name="type" checked="checked" value="guest">In House</input>
<input type="radio" name="type" value="walk_in">Walk In</input>
</form>.
Update
Tried onChange() too but not working.
It fires. Check demo http://jsfiddle.net/yeyene/kbAk3/
$("#inline_content input[name='type']").click(function(){
alert('You clicked radio!');
if($('input:radio[name=type]:checked').val() == "walk_in"){
alert($('input:radio[name=type]:checked').val());
//$('#select-table > .roomNumber').attr('enabled',false);
}
});
There are a couple of things wrong in this code:
You're using <input> the wrong way. You should use a <label> if you want to make the text behind it clickable.
It's setting the enabled attribute, which does not exist. Use disabled instead.
If it would be an attribute, it's value should not be false, use disabled="disabled" or simply disabled without a value.
If checking for someone clicking on a form event that will CHANGE it's value (like check-boxes and radio-buttons), use .change() instead.
I'm not sure what your code is supposed to do. My guess is that you want to disable the input field with class roomNumber once someone selects "Walk in" (and possibly re-enable when deselected). If so, try this code:
HTML:
<form class="type">
<p>
<input type="radio" name="type" checked="checked" id="guest" value="guest" />
<label for="guest">In House</label>
</p>
<p>
<input type="radio" name="type" id="walk_in" value="walk_in" />
<label for="walk_in">Walk in</label>
</p>
<p>
<input type="text" name="roomnumber" class="roomNumber" value="12345" />
</p>
</form>
Javascript:
$("form input:radio").change(function () {
if ($(this).val() == "walk_in") {
// Disable your roomnumber element here
$('.roomNumber').attr('disabled', 'disabled');
} else {
// Re-enable here I guess
$('.roomNumber').removeAttr('disabled');
}
});
I created a fiddle here: http://jsfiddle.net/k28xd/1/
Personally, for me, the best solution for a similar issue was:
HTML
<input type="radio" name="selectAll" value="true" />
<input type="radio" name="selectAll" value="false" />
JQuery
var $selectAll = $( "input:radio[name=selectAll]" );
$selectAll.on( "change", function() {
console.log( "selectAll: " + $(this).val() );
// or
alert( "selectAll: " + $(this).val() );
});
*The event "click" can work in place of "change" as well.
Hope this helps!
A different way
$("#inline_content input[name='type']").change(function () {
if ($(this).val() == "walk_in" && $(this).is(":checked")) {
$('#select-table > .roomNumber').attr('enabled', false);
}
});
Demo - http://jsfiddle.net/cB6xV/
Seems like you're #inline_content isn't there! Remove the jQuery-Selector or check the parent elements, maybe you have a typo or forgot to add the id.
(made you a jsfiddle, works after adding a parent <div id="inline_content">: http://jsfiddle.net/J5HdN/)
put ur js code under the form html or use $(document).ready(function(){}) and try this.
$('#inline_content input[type="radio"]').click(function(){
if($(this).val() == "walk_in"){
alert('ok');
}
});

trouble with jquery and traversing the DOM to select the appropriate elements

Hello guys i have the below html for a number of products on my website,
it displays a line with product title, price, qty wanted and a checkbox called buy.
qty input is disabled at the moment.
So what i want to do is,
if the checkbox is clicked i want the input qty to set to 1 and i want it to become enabled.
I seem to be having some trouble doing this. Could any one help
Now i can have multiple product i.e there will be multiple table-products divs within my html page.
i have tried using jQuery to change the details but i dont seem to be able to get access to certain elements.
so basically for each table-product i would like to put a click listener on the check box that will set the value of the input-text i.e qty text field.
so of the below there could be 20 on a page.
<div class="table-products">
<div class="table-top-title">
My Spelling Workbook F
</div>
<div class="table-top-price">
<div class="price-box">
<span class="regular-price" id="product-price-1"><span class="price">€6.95</span></span>
</div>
</div>
<div class="table-top-qty">
<fieldset class="add-to-cart-box">
<input type="hidden" name="products[]" value="1"> <legend>Add Items to Cart</legend> <span class="qty-box"><label for="qty1">Qty:</label> <input name="qty1" disabled="disabled" value="0" type="text" class="input-text qty" id="qty1" maxlength="12"></span>
</fieldset>
</div>
<div class="table-top-details">
<input type="checkbox" name="buyMe" value="buy" class="add-checkbox">
</div>
<div style="clear:both;"></div>
</div>
here is the javascript i have tried
jQuery(document).ready(function() {
console.log('hello');
var thischeck;
jQuery(".table-products").ready(function(e) {
//var catTable = jQuery(this);
var qtyInput = jQuery(this).children('.input-text');
jQuery('.add-checkbox').click(function() {
console.log(jQuery(this).html());
thischeck = jQuery(this);
if (thischeck.is(':checked'))
{
jQuery(qtyInput).first().val('1');
jQuery(qtyInput).first().prop('disabled', false);
} else {
}
});
});
// Handler for .ready() called.
});
Not the most direct method, but this should work.
jQuery(document).ready(function() {
jQuery('.add-checkbox').on('click', function() {
jQuery(this)
.parents('.table-products')
.find('input.input-text')
.val('1')
.removeAttr('disabled');
});
});
use
jQuery('.add-checkbox').change(function() {
the problem is one the one hand that you observe click and not change, so use change rather as it really triggers after the state change
var qtyInput = jQuery(this).children('.input-text');
another thing is that the input is no direct child of .table-products
see this fiddle
jQuery('input:checkbox.add-checkbox').on('change', function() {
jQuery(this)
.parent()
.prev('div.table-top-qty')
.find('fieldset input:disabled.qty')
.val(this.checked | 0)
.attr('disabled', !this.checked);
});
This should get you started in the right direction. Based on jQuery 1.7.2 (I saw your prop call and am guessing that's what you're using).
$(document).ready(function() {
var thischeck;
$('.table-products').on('click', '.add-checkbox', function() {
var qtyInput = $(this).parents('.table-products').find('.input-text');
thischeck = $(this);
if (thischeck.prop('checked')) {
$(qtyInput).val('1').prop('disabled', false);
} else {
$(qtyInput).val('0').prop('disabled', true);
}
});
});
Removing the property for some reason tends to prevent it from being re-added. This works with multiple tables. For your conflict, just replace the $'s with jQuery.
Here's the fiddle: http://jsfiddle.net/KqtS7/5/

Categories