check the 'checked' value of all children checkboxes - javascript

Sorry, my JS is not the best, I need some help on something I am sure is simple.
Basically I have my parent node (it can change, but that's okay, I'm getting the Parent correctly), but I now need to know if every child checkbox of that parent is checked (if so return 1) or if 1 or more child checkboxes is unchecked return 0.
Any help would be great!

I think :not combined with :checked is what you want
var numUnchecked =
$(parentNode).find("input[type='checkbox']:not(:checked)").length;
if (numUnchecked > 0)
alert("Some not checked");
Here's a fiddle
So for your specific question, it would be something like this
function areAllChecked() {
var parentNode = $("#parent");
var numUnchecked =
parentNode.find("input[type='checkbox']:not(:checked)").length;
return numUnchecked > 0 ? 0 : 1;
}

Related

Javascript disabled button if checkboxes are not choosen - problem

I wrote a code, that make the button not disabled when you check at least one checkbox with class "sum".
I want to change the code, so I have to classes for and you can check only one checkbox (or two of them) to make the button not disabled.
This is what I have and it works with only one class:
var checkBoxes = $('.sum');
checkBoxes.change(function () {
$('#dashboardbuttonpay').prop('disabled', checkBoxes.filter(':checked').length < 1);
});
$('.sum').change();
});
This is what I tried to do, but OR op does not work:
var checkBoxes = $('.sum' || **'.checkAll'**);
checkBoxes.change(function () {
$('#dashboardbuttonpay').prop('disabled', checkBoxes.filter(':checked').length < 1);
});
$('.sum' || **'.checkAll'**).change();
});
The code works with && operator, but I do not need this.
Using the OR operation on strings this way does not make sense. If you do this with two non-empty strings, you always get the first operand:
console.log('a' || 'b')
In order to select multiple elements, you just separate them by comma:
var checkBoxes = $('.sum, .checkAll');
The code works with && operator, but I do not need this.
Not really. 'a' && 'b' always returns 'b'.
You could check for the amount of checked inputs then add/remove the disabled property in the change event handler.
var checkBoxes = $('.sum','.checkAll');
checkBoxes.change(function () {
if (checkBoxes.filter(':checked').length > 0) {
$('#dashboardbuttonpay').prop('disabled', null);
} else {
$('#dashboardbuttonpay').prop('disabled');
}
});
This way you capture if one or more checkboxes are checked before remove the disabled attribute of the button. Which lets you enable the button with either one or both checkboxes selected.
var checkBoxes = $('.sum','.checkAll');
checkBoxes.change(function () {
if(checkBoxes.filter(':checked').length > 1)
$('#dashboardbuttonpay').prop('disabled',true);
else
$('#dashboardbuttonpay').prop('disabled',false);
});

Jquery checkbox affect one item not all items

I was wondering if someone can help me please, I have a series of checkboxes that when clicked change the div background, activate 2 inputs and add a tick icon. My issue is that when one check box is checked the class .TickIco shows for all and so does the .disableToggle
How can i get it so that this only affects one .checkBG at a time and not all of them?
Hopefully this JSFiddle will help explain what I mean.
https://jsfiddle.net/jayjay89/xfg96we5/
thanks
$(".checkBG").click(function () {
var checked = $(this).is(':checked');
var location = $(this).parent().parent().parent();
if (checked) {
$(this).parent().parent().parent().addClass("activeformBlock");
$(".tickIco").show();
$(".disabletoggle").removeAttr("disabled");
} else {
$(this).parent().parent().parent().removeClass("activeformBlock");
$(".tickIco").hide();
$(".disabletoggle").attr('disabled', 'disabled');
}
});
thanks
you can use the context in which the selector will be looked.
You already have the location variable which is the parent context for one of your row
$(".checkBG").click(function () {
var checked = $(this).is(':checked');
var location = $(this).parent().parent().parent();
if (checked) {
$(this,location).parent().parent().parent().addClass("activeformBlock");
$(".tickIco",location).show();
$(".disabletoggle",location).removeAttr("disabled");
} else {
$(this,location).parent().parent().parent().removeClass("activeformBlock");
$(".tickIco",location).hide();
$(".disabletoggle",location).attr('disabled', 'disabled');
}
});
Your issue lies in the way you are selecting the .tickIco and .disabletoggle elements:
$(".tickIco").show();
$(".disabletoggle").removeAttr("disabled");
These jquery calls use selectors that match all classes of .tickIco and .disabletoggle.
Dirty solution (finds elements of the parent with matching classes using .find()):
$(this).parent().parent().parent().find(".tickIco").show();
$(this).parent().parent().parent().find('.disabletoggle').removeAttr("disabled")
Better solution:
jQuery selecter takes the context of your selection as a second argument so you can:
var context = $(this).parent().parent().parent();
$(".tickIco", context).show();
$('.disabletoggle', context).removeAttr("disabled")

Combining checkbox selectors for unique results in jQuery

I have 3 checkboxes, and I want all combinations of those checkboxes to display a different result, but I cannot work out how to do so. It feels like there's a simple way of doing this that I'm missing.
Here's the Frankenstein monster-code I have so far, which doesn't do what I'd like it to. The aim is that the following code sees that a user has has checked both the "webcam" (#checkWebcam) and "chat" (#checkChat) boxes, and that a different download link is being displayed based on that selection combo...
jQuery('#checkWebcam, #checkChat').change(function() {
var isChecked = jQuery('#checkWebcam, #checkChat').is(':checked');
if(isChecked)
jQuery('div.strip.download').html('Download');
else
jQuery('div.strip.download').html('Download');
});
Could anyone help me with how to actually achieve this aim? Thank you in advance.
This will do an OR operation,
var isChecked = jQuery('#checkWebcam, #checkChat').is(':checked');
what you basically need is to perform an AND opereation here, so use
var isChecked = jQuery('#checkWebcam').is(':checked') && $('#checkChat').is(':checked');
You can try this code :
if ( $("#checkWebcam:checked, #checkChat:checked").length == 2 ) {
//your code
}
var isChecked = jQuery('#checkWebcam, #checkChat').is(':checked'); will return true if either one or both are selected.
Modify your code as
jQuery('#checkWebcam, #checkChat').change(function() {
var boxs = jQuery('#checkWebcam, #checkChat');
var checked = boxs.filter(':checked'); //Filter checked checkboxes
if(boxs.length == checked.length){ //if length are same
alert('both are checked')
}else{
alert('both are not checked')
}
});
DEMO

find ID of previous button

I'm looking to find the id of the previous button. It is pretty far away - lots of table rows, tables, divs, etc. between the target and the button but I thought this would still work:
alert( $(this).prevAll("input[type=button]").attr('id') );
Unfortunately this returns alerts 'undefined'. Help?
function getPrevInput(elem){
var i = 0,
inputs = document.getElementsByTagName('input'),
ret = 'Not found';
while(inputs[i] !== elem || i >= inputs.length){
if(inputs[i].type === 'button'){
ret = inputs[i];
}
i++;
}
return (typeof ret === 'string') ? ret : ret.id;
}
That probably isn't the most efficient solution, but it's the only one I can think of. What it does is goes through all the input elements and finds the one right before the one you passed into the function. You can use it like this, assuming you're calling it correctly and this is the input element:
getPrevInput(this);
Demo
That kind of lookup might be expensive. What about doing a select for all your input[type=button] elements, and traversing that array until you find the element matching your id. Then you can simply reference the array index - 1 to get your answer.
Is the previous button a sibling of the current button? If not, prevAll() won't work. The description of prevAll():
Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector.
Depending on your DOM structure, you can use a combination of parents() and then followed by find().
This function looks up all input[type=button] elements and uses the jQuery index function to find your current element in this group.
If it could be found and there is a previous element it is returned.
$.fn.previousElem = function(lookup){
var $elements = $(lookup),
index = $elements.index(this);
if(index > 0){
return $elements.eq(index-1)
}else{
return this;
}
}
HTML:
<div><div><div><div>
<input type=button id=1 value=1 />
</div></div></div></div>
<div><div><div><div>
<input type=button id=2 value=2 />
</div></div></div></div>
JS:
alert ($("#2").previousElem('input[type=button]').attr('id'))
http://jsfiddle.net/SnScQ/1/
Here's a different version of Amaan's code, but jqueryfied and his solution wasn't looking for a button. The key to the solution is that jQuery returns the elements in document order, as do document.getElementsByTagName and similar functions.
var button = $('#c');
var prevNode;
$("input[type=button]").each(function() {
if (this == button[0]) {
return false;
}
prevNode = this;
});
alert(prevNode && prevNode.getAttribute('id'));
http://jsfiddle.net/crFy6/
have you tried .closest? ...
alert( $(this).closest("input[type=button]").attr('id') );

Can't get javascript/jquery to sort elements correctly more than one time

I have child divs that I'm trying to sort based on a jquery .data() value that I give them that is just a single number. This code works perfectly, but only once, after that I can't figure out how the heck it's sorting them. Here is a simplified version:
var myArray = $('#container div').get();
myArray.sort(function(x,y) {
return $(x).data('order') - $(y).data('order');
});
$('#container').empty().append(myArray);
I've tried so many other different methods of sorting, other plugins, etc., and I can't get anything to work right. This is as close as I can get. I just have this running on a jquery change event.
Here is the whole thing in case I'm doing something stupid elsewhere:
$('#attorneyFilter').change(function() {
//get array of links for sorting
var myArray = $('#attorneyBlocks div').get();
var selectedArea = $(this).val();
//sort alphabetically when "all" is selected
if (selectedArea == 'all') {
$('#attorneyBlocks div').show();
myArray.sort(function(a,b) {
return $(a).text() > $(b).text() ? 1 : -1;
});
//filter attorneys based on practice area and then assign its order# to the div with data, getting all values from the div's class
} else {
$('#attorneyBlocks div').hide().each(function() {
var attorneyArea = $(this).attr('class').split(', ');
for (var i=0;i<attorneyArea.length;i++) {
var practiceArea = attorneyArea[i].split('-');
if (selectedArea == practiceArea[0]) {
$(this).show().data('order',practiceArea[1]);
}
}
});
//sort based on order, the lower the number the higher it shows up
myArray.sort(function(x,y) {
return $(x).data('order') - $(y).data('order');
});
}
//append order back in
$('#attorneyBlocks').empty().append(myArray);
});
And a link to the page in question
Here's a jsFiddle with this working using .detach() instead of .empty() to keep the data.
http://jsfiddle.net/shaneblake/Tn9u8/
Thanks for the link to the site, that made it clear.
It seems to me you never clear out the data from the prior time. You hide everything but maybe something like this will solve your problem (here I set everything hidden to the bottom, you can clear it or use a different value -- as long as it is not the same as any sort key):
$('#attorneyBlocks div').hide().data('order',999999).each(function() {
var attorneyArea = $(this).attr('class').split(', ');
for (var i=0;i<attorneyArea.length;i++) {
var practiceArea = attorneyArea[i].split('-');
if (selectedArea == practiceArea[0]) {
$(this).show().data('order',practiceArea[1]);
}
}
});
Also, the code on the server is missing the 2nd line you have above:
var myArray = $('#attorneyBlocks div').get();
The problem is the change event is tied to the original items. After the sort you make all new items. They don't have any event tied to them. You will need to use .live()
Eventually figured it out, the data values from hidden divs were screwing with my sorting, so I changed my sorting code to only pay attention to :visible divs and that did the trick. Doh! Thanks for your help everyone.

Categories