I'm trying to get the order of which checkboxes have been checked.
<ul class="dropdown-content checkboxes">
<li><label><input type="checkbox" />Billy</label></li>
<li><label><input type="checkbox" />Jacob</label></li>
<li><label><input type="checkbox" />Bob</label></li>
<li><label><input type="checkbox" />Alexandren</label></li>
<li><label><input type="checkbox" />Erren</label></li>
<li><label><input type="checkbox" />Stewgart</label></li>
<li><label><input type="checkbox" />Jillian</label></li>
<li><label><input type="checkbox" />Other</label></li>
</ul>
I came up with this but i'm unable to get the order of when the checkboxes were checked. I'm only able to get the list of which ones are checked only.
$(":checkbox").click(function() {
console.log($(":checked").length);
var i = 0;
checked = true;
$(':checkbox').each(function() {
if (this.checked == false) {
i++;
if (i === 8) {
checked = false;
}
}
});
});
How would I get the data of what order they were checked? for instance "Checkboxes 1, 6, 3 ,2 were checked in this order"
You'll have keep track of what checkboxes are checked, for instance in an array
var order = [];
$("[type=checkbox]").on('change', function() { // always use change event
var idx = order.indexOf(this);
if (idx !== -1) { // if already in array
order.splice(idx, 1); // make sure we remove it
}
if (this.checked) { // if checked
order.push(this); // add to end of array
}
// <------------------------------------For demonstration
$('#result').html(JSON.stringify($.map(order, function(elem) {
return $(elem).closest('label').text().trim();
})));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="dropdown-content checkboxes">
<li><label><input type="checkbox" />Billy</label></li>
<li><label><input type="checkbox" />Jacob</label></li>
<li><label><input type="checkbox" />Bob</label></li>
<li><label><input type="checkbox" />Alexandren</label></li>
<li><label><input type="checkbox" />Erren</label></li>
<li><label><input type="checkbox" />Stewgart</label></li>
<li><label><input type="checkbox" />Jillian</label></li>
<li><label><input type="checkbox" />Other</label></li>
</ul>
<div id="result"></div>
To get the index of each checkbox, or more accurately the parent LI, you could just map them
var map = $.map(order, function(elem) {
return $(elem).closest('li').index();
});
FIDDLE
You can do it in pure JavaScript too:
var result = document.getElementById('result');
var order = [];
[].forEach.call(document.querySelectorAll('input[type="checkbox"]'), function (checkbox) {
'use strict';
checkbox.addEventListener('change', function () {
var previousLi = checkbox.parentNode.parentNode.previousElementSibling;
var index = 0;
while (previousLi !== null) {
previousLi = previousLi.previousElementSibling;
index += 1;
}
if (checkbox.checked) {
order.push(index);
} else {
order.splice(order.indexOf(index), 1);
}
result.textContent = order;
});
});
<ul class="dropdown-content checkboxes">
<li><label><input type="checkbox"/>Billy</label></li>
<li><label><input type="checkbox"/>Jacob</label></li>
<li><label><input type="checkbox"/>Bob</label></li>
<li><label><input type="checkbox"/>Alexandren</label></li>
<li><label><input type="checkbox"/>Erren</label></li>
<li><label><input type="checkbox"/>Stewgart</label></li>
<li><label><input type="checkbox"/>Jillian</label></li>
<li><label><input type="checkbox"/>Other</label></li>
</ul>
<p id="result"></p>
In the above code, for each checkbox we invoke function, which on it's change will:
get index of our input's li in it's parent,
either
add it at the end of an array on check, or
remove appropriate element of an array on uncheck, and
present an array (for demonstration purposes).
You would need to bind to the checkboxes being clicked, and push to an array some information corresponding to the checkboxes, then search through the array, their position would be the order in which they were checked.
Related
I have a list of products that will get checked if I click select all. What I want to do is when all the checkboxes are checked and I uncheck just one checkbox, it should only uncheck the clicked element not all of the elements.
$('#selectAll').change(function () {
$('#pfilters li input').prop('checked', this.checked);
});
Do you mean like that?
$('#selectAll').change(function () {
$('#pfilters li input').prop('checked', this.checked);
});
function isAllSelected() {
return $('#pfilters li input').length === $('#pfilters li input:checked').length;
}
$('#pfilters li input').on('change', function() {
$('#selectAll').prop('checked', isAllSelected());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<ul>
<li>
<label><input type="checkbox" id="selectAll"/>Select All</label>
</li>
</ul>
<ul id="pfilters">
<li><label><input type="checkbox">Select Product 1</label></li>
<li><label><input type="checkbox">Select Product 2</label></li>
<li><label><input type="checkbox">Select Product 3</label></li>
</ul>
</form>
I'm using Asp.Net CheckBoxList control and I have a lot of checkboxes inside li elements. I want to change background color of li elements if the checkbox is checked inside it. I tried lots of things with css and jquery but i couldn't do it.
Note: Some of the answers given below are working when I click checkboxes. But when the page is postback, the checked boxes are turning to default view.
<ul id="ContentPlaceHolder1_CheckBoxList1">
<li><input id="c1" type="checkbox" name="c1" value="57" /><label for="c1">aaaaaaaaa</label></li>
<li><input id="c2" type="checkbox" name="c2" value="94" /><label for="c2">bbbbbbbbbb</label></li>
<li><input id="c3" type="checkbox" name="c3" value="121" /><label for="c3">cccccccccc</label></li>
</ul>
Some of my tries:
<!-- 1 -->
var ccc = function () {
$("input:checked").parent("li").css({"color": "white", "background-color": "blue"});
};
ccc();
$( "input[type=checkbox]" ).on( "click", ccc );
<!-- 2 -->
$(":checkbox").click(function(){
$(":checked").parent().css({"color": "white", "background-color": "blue"});
});
/*1*/
li < input[type=checkbox]:checked {
background-color:aqua;
}
/*2*/
li:has( input[type="checkbox"]:checked) {
background: #000;
border-color: green;
color: white;
}
Use jquery is() function and elem.closest() function.You can add or remove class based on input condition using change event
$(document).on('change','#ContentPlaceHolder1_CheckBoxList1 input[type=checkbox]',function(){
if($(this).is(':checked')){
$(this).closest('li').addClass('checked_class')
}else{
$(this).closest('li').removeClass('checked_class')
}
})
.checked_class{
border:1px solid red;
/*add your desgin properties*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="ContentPlaceHolder1_CheckBoxList1">
<li>
<input id="c1" type="checkbox" name="c1" value="57" />
<label for="c1">aaaaaaaaa</label>
</li>
<li><input id="c2" type="checkbox" name="c2" value="94" /><label for="c2">bbbbbbbbbb</label></li>
<li><input id="c3" type="checkbox" name="c3" value="121" /><label for="c3">cccccccccc</label></li>
</ul>
Using vanilla javascript you could do the following. Using the change event listener you can check whether the checkbox has been checked or not. If it evaluates true it means it has been checked by the user. In that case you can get its parent by using parentNode object on the element to get manipulate its styles.
const inputs = document.querySelectorAll('input');
const color = ['blue', 'red', 'yellow'];
inputs.forEach((input, index) => {
input.addEventListener('change', function(){
if(this.checked){
this.parentNode.style.background = color[index]
}
})
})
Thanks everybody. I solved the problem your way (mixing your answers).
I used two functions. One of them is working on page load and controlling all checkboxes if they are checked or not, other is working when a checkbox changes.
$(document).ready(function () {
$("input").each(function (index) {
if ($(this).is(':checked')) {
$(this).parent().css('background-color', 'blue');
}
else {
$(this).parent().css('background-color', '#eee');
}
});
});
$('#ContentPlaceHolder1_CheckBoxList1 input[type=checkbox]').on('change', function () {
if ($(this).is(':checked')) {
$(this).parent().css('background-color', 'blue');
}
else {
$(this).parent().css('background-color', '#eee');
}
});
With usual Javascript:
window.onload = function a() {
document.querySelectorAll("li").forEach(function(e) {
if (e.children[0].checked == true) e.style.backgroundColor = "green";
else e.style.backgroundColor = "";
e.onchange = a;
})
}
<ul id="ContentPlaceHolder1_CheckBoxList1">
<li><input id="c1" type="checkbox" name="c1" value="57" /><label for="c1">aaaaaaaaa</label></li>
<li><input id="c2" type="checkbox" name="c2" value="94" /><label for="c2">bbbbbbbbbb</label></li>
<li><input id="c3" type="checkbox" name="c3" value="121" /><label for="c3">cccccccccc</label></li>
</ul>
You want to listen to the change event of the checkbox, then target the parent element (li). My example below simply changes the background of the li using $.css(). You could add a class using .addClass("className").
Edit: I've updated my answer now you need on load behaviour.
The code below uses a ES6 style function definition using an arrow functions. It takes 2 parameters (id, isChecked) and updates the css accordingly. toggleStyle function uses the ternary operator which is equivalent to an if{} else{} block.
// on load
$(document).ready(function(){
$('li input[type=checkbox]').each(function() {
// pass the id and isChecked to toggleColour
toggleStyle(this.id, $(this).is(':checked'));
});
});
// on change
$('li input[type=checkbox]').on('change', function() {
// pass the id and isChecked to toggleColour
toggleStyle(this.id, $(this).is(':checked'));
});
// ES6 function defn to toggle colour/style
var toggleStyle = (id, isChecked) =>
{
isChecked ? $('#'+id).parent().css('background', '#ff0')
: $('#'+id).parent().css('background', '#fff')
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="ContentPlaceHolder1_CheckBoxList1">
<li><input id="c1" type="checkbox" name="c1" value="57" /><label for="c1">aaaaaaaaa</label></li>
<li><input id="c2" type="checkbox" name="c2" value="94" checked /><label for="c2">bbbbbbbbbb</label></li>
<li><input id="c3" type="checkbox" name="c3" value="121" /><label for="c3">cccccccccc</label></li>
</ul>
I've been looking for some code which basically moves checkboxes to the top of a list once they have been checked.
I came accross Move checkboxes on checked jQuery which gave me a great start, but I'm now stuck on a further issue.
If I add an <li> item into this <ul> list, but its just a standard item without an <input> section, it stops the whole code from working.
Is there a simple work around for this that I haven't seen? I'm struggling to be honest as I'm just starting with JQuery, so its quite new to me.
Using the code for the previous question. We can add the "typeof" to check if there's an input inside the li. This avoids the issue and remains the li static.
var list = $("ul"),
origOrder = list.children();
list.on("click", ":checkbox", function() {
var i, checked = document.createDocumentFragment(),
unchecked = document.createDocumentFragment();
for (i = 0; i < origOrder.length; i++) {
if (typeof(origOrder[i].getElementsByTagName("input")[0]) != "undefined" && origOrder[i].getElementsByTagName("input")[0].checked) {
checked.appendChild(origOrder[i]);
} else {
unchecked.appendChild(origOrder[i]);
}
}
list.append(checked).append(unchecked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<ul>
<li><label><input type="checkbox" id="one" />One</label></li>
<li><label><input type="checkbox" id="two" />Two</label></li>
<li><label><input type="checkbox" id="three" />Three</label></li>
<li><label><input type="checkbox" id="four" />Four</label></li>
<li><label><input type="checkbox" id="five" />Five</label></li>
<li><p>Hello World!</p></li>
</ul>
I have a series of checkboxes, meals and products. I am able to check each one and find the name and value. What I want to do and unable to do is create an array, the array index would be the name of the checkbox and the value would be the value of the checkbox that was checked.
$("#recipe-filter-form").submit(function(e) {
e.preventDefault();
var categories = [];
var i = 0;
$('.category-checkbox').each(function (index, value) {
var checkboxName = $(this).attr('name');
var checkboxValue = $(this).val();
// if checkbox is checked
if ($(this).is(':checked'))
{
categories[checkboxName][i] = checkboxValue;
i++;
}
});
console.log(categories);
});
This loops thru each checkbox, if it is checked, lets get the name and value.
I added an index i to the array in hopes of it working but it returns an error: TypeError: Cannot set property '0' of undefined
HTML
<form action="" method="get" id="recipe-filter-form">
<ul>
<li>
<label class="check" data-category="appetizers">
<input type="checkbox" name="meal" value="appetizers" class="category-checkbox"> Appetizers</label>
</li>
<li>
<label class="check" data-category="beverages">
<input type="checkbox" name="meal" value="beverages" class="category-checkbox"> Beverages</label>
</li>
</ul>
<ul>
<li>
<label class="check" data-category="sides">
<input type="checkbox" name="products" value="sides" class="category-checkbox"> Sides</label>
</li>
<li>
<label class="check" data-category="soups">
<input type="checkbox" name="products" value="soups" class="category-checkbox"> Soups</label>
</li>
</ul>
<button type="submit" class="button green secondary">Filter</button>
</form>
If every checkbox was checked, my expected output is:
array('meal' => array('appetizers', beverages'), 'products' => array('sides', 'soups')
Why do I want to create a multi dimensional array?
Because after the array is created, I will generate a string by looping thru the array by appending the array index, values for a string to look like:
meal=appetizers,beverages&products=sides,soups
Question: How do I alter my code to get the expected output as seen on the line above?
I believe you were having problems in the code you posted.
categories[checkboxName][i] here categories[checkboxName] is undefined in the first attempt. So it will cause error.
i is not needed. Just use push().
You can use categories[checkboxName] = categories[checkboxName] || []; to initialize the variable as an array if it is undefined in the loop.
$("#recipe-filter-form").submit(function(e) {
e.preventDefault();
var categories = [];
$('.category-checkbox').each(function(index, value) {
var checkboxName = this.name;
var checkboxValue = this.value;
// if checkbox is checked
if ($(this).is(':checked')) {
categories[checkboxName] = categories[checkboxName] || []; //initialize if not exist
categories[checkboxName].push(checkboxValue);
}
});
console.log(categories);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form action="" method="get" id="recipe-filter-form">
<ul>
<li>
<label class="check" data-category="appetizers">
<input type="checkbox" name="meal" value="appetizers" class="category-checkbox">Appetizers</label>
</li>
<li>
<label class="check" data-category="beverages">
<input type="checkbox" name="meal" value="beverages" class="category-checkbox">Beverages</label>
</li>
</ul>
<ul>
<li>
<label class="check" data-category="sides">
<input type="checkbox" name="products" value="sides" class="category-checkbox">Sides</label>
</li>
<li>
<label class="check" data-category="soups">
<input type="checkbox" name="products" value="soups" class="category-checkbox">Soups</label>
</li>
</ul>
<button type="submit" class="button green secondary">Filter</button>
</form>
I have a script that will check and uncheck all children checkboxes in a nested list. I am now trying to get it so I can check a low level checkbox and it will check all the parents only back up to the highest level. Here is a JSFiddle
<ul class="tree" id="tree">
<li><input type="checkbox" name="account_settings" value="yes">Account Settings <!-- AND SHOULD CHECK HERE -->
<ul>
<li><input type="checkbox" name="one" value="one">AS One</li>
<li><input type="checkbox" name="two" value="two">AS Two</li>
<li><input type="checkbox" name="user_roles" value="user_roles">Users & Roles <!-- SHOULD CHECK HERE -->
<ul>
<li><input type="checkbox" name="user_role" value="add">Add</li>
<li><input type="checkbox" name="user_role" value="delete">Delete</li> <!-- CHECK HERE -->
</ul>
</li>
</ul>
</li>
<li><input type="checkbox" name="rl_module" value="yes">RL Module</li>
<li><input type="checkbox" name="rl_module" value="yes">Accounting
<ul>
<li><input type="checkbox" name="vat" value="yes">VAT</li>
<li><input type="checkbox" name="bank_account" value="yes">Banking
<ul>
<li><input type="checkbox" name="view" value="yes">View</li>
<li><input type="checkbox" name="crud" value="yes">CRUD</li>
</ul>
</li>
</ul>
</li>
</ul>
And the corresponding javascript:
$('input[type=checkbox]').click(function(){
// if is checked
if($(this).is(':checked')){
// check all children
$(this).parent().find('li input[type=checkbox]').prop('checked', true);
// check all parents
$(this).parent().prev().prop('checked', true);
} else {
// uncheck all children
$(this).parent().find('li input[type=checkbox]').prop('checked', false);
}
});
It looks like you want something like this
$('input[type=checkbox]').click(function(){
if(this.checked){ // if checked - check all parent checkboxes
$(this).parents('li').children('input[type=checkbox]').prop('checked',true);
}
// children checkboxes depend on current checkbox
$(this).parent().find('input[type=checkbox]').prop('checked',this.checked);
});
FIDDLE
If you want to check up and down hierarchy - you can do it like this
$('input[type=checkbox]').click(function(){
// children checkboxes depend on current checkbox
$(this).next().find('input[type=checkbox]').prop('checked',this.checked);
// go up the hierarchy - and check/uncheck depending on number of children checked/unchecked
$(this).parents('ul').prev('input[type=checkbox]').prop('checked',function(){
return $(this).next().find(':checked').length;
});
});
FIDDLE
This should do it:
$('input[type=checkbox]').click(function () {
$(this).parent().find('li input[type=checkbox]').prop('checked', $(this).is(':checked'));
var sibs = false;
$(this).closest('ul').children('li').each(function () {
if($('input[type=checkbox]', this).is(':checked')) sibs=true;
})
$(this).parents('ul').prev().prop('checked', sibs);
});
jsFiddle example
Latest update handles up and down the hierarchy, and siblings.
Just use jquery.parents(). It is somewhat similar to find() except it searches all parents. Something like this might be close to what you are looking for:
$(this).parents('li').each(function() {
$(this).children('input').prop('checked', true);
});
See http://api.jquery.com/parents/ for more information.
EDIT: Alright, here is a solution that works:
http://jsfiddle.net/3y3Pb/12/
EDIT2: And a more streamlined solution here:
http://jsfiddle.net/3y3Pb/14/
Have a JSFiddle: http://jsfiddle.net/3y3Pb/16/
I would recommend adding a parent attribute to the checkboxes. This parent attribute will reference the parent checkbox's id so that you don't have to worry about your structure changing:
$('input type=[checkbox]').change(function () {
$('#' + $(this).attr('parent')).prop('checked', this.checked);
});
Ex:
<input type="checkbox" name="account_settings" value="yes" id="as">Account Settings
<ul>
<li><input type="checkbox" name="one" value="one" parent="as" id="one">AS One</li>
You can use prevAll() also
I have the same issue. In my case there are multiple checkboxes in li with labels, and each checkbox above target have class parent (generated in js)
$(this).parents().prevAll('input:checkbox.parent').each(function () {
$(this).attr('checked', true);
});