JQuery move items in list when checked - javascript

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>

Related

finding the order of which checkboxes have been checked

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.

Assigning checkbox values to variables

I've got a list of possible checkboxes and the user can select up to three options. What I'm struggling with is how to recognize which boxes are checked, and then assign them to variables (to send in a later ajax call). So far the code I've written seems to just take the first three checkbox values regardless of whether they are checked or not and use those in my ajax call. Please help me figure out where I've gone wrong.
Here's my HTML:
<ul id="Names" class="stateNames">
<li>Alabama
<ul class="airports">
<li><input type="checkbox" class="destination"/> Birmingham, AL</li>
<li><input type="checkbox" class="destination"/> Huntsville, AL</li>
</ul>
<li>Alaska
<ul class="airports">
<li><input type="checkbox" class="destination"/> Anchorage, AK</li>
<li><input type="checkbox" class="destination"/> Fairbanks, AK</li>
<li><input type="checkbox" class="destination"/> Juneau, AK</li>
</ul>
</li>
</ul>
<input type="button" onclick="clickHandler()" value="Submit" />
Here's my javascript/jquery:
function clickHandler() {
endLocDest1 = "";
endLocDest2 = "";
endLocDest3 = "";
for(i = 0; i < document.getElementsByClassName('destination').length; i++) {
if (document.getElementsByClassName('destination')[i].checked) {
endLocDest1 = document.getElementsByClassName('destination')[0].value;
endLocDest2 = document.getElementsByClassName('destination')[1].value;
endLocDest3 = document.getElementsByClassName('destination')[2].value;
}
alert(endLocDest1 + endLocDest2 + endLocDest3);
};
}
I've also put this code into a fiddle http://jsfiddle.net/6ywm1n6h/3/ (which currently doesn't return anything).
Thanks in advance!
In your jsfiddle, you had jQuery turned on, assuming that, try using ...
$(".destination:checked")
Which will return all checked; you can use this as an array and determine which are clicked.
EDIT:
You can assign this to a variable, say ...
var checked_values = $(".destination:checked");
... then loop through and do what you need.
for (var i=0,len=checked_values.length; i<len; i++) {
console.log(checked_values[i].attr("id"));
}
If your code is wrapped in <form> and </form> then checked inputs will be sent automatically when form is submitted (normaly or AJAX'ed). Your mistake is that you do not set names nor values to your checkboxes. Try:
<input type="checkbox" name="airport[alabama][]" value="Birmingham">
<input type="checkbox" name="airport[alabama][]" value="Huntsville">
<input type="checkbox" name="airport[alaska][]" value="Anchorage">
<input type="checkbox" name="airport[alaska][]" value="Fairbanks">
and see print_r($_POST) or print_r($_GET) (depending on your form method) in page which receives form submission.

Jquery Check parent checkboxes in nested ul li

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);
});

Making a checkbox appear at the bottom of the unordered list when checked

http://jsfiddle.net/AGinther/ZF7bD/1/
I am trying to make a list item appear at the bottom of the list when a checkbox is clicked using jQuery, currently I have;
HTML
<ul>
<li><input type="checkbox" id="checkbox-1"><label for="checkbox-1"> Checkbox 1</label></li>
<li><input type="checkbox" id="checkbox-2"><label for="checkbox-2"> Checkbox 2</label></li>
<li><input type="checkbox" id="checkbox-3"><label for="checkbox-3"> Checkbox 3</label></li>
<li><input type="checkbox" id="checkbox-4"><label for="checkbox-4"> Checkbox 4</label></li>
</ul>
Javascript
if ($('input[type="checkbox"]').prop('checked')) {
//Some code goes here...
}
Firstly, you need to include jQuery as a library in your fiddle. Furthermore, your if statement doesn't bind to any events.
You can do this by binding to the click event for checkboxes.
$('input[type="checkbox"]').click(function() {
var $t = $(this);
if ($t.is(':checked')) {
var cb = $t.parent().remove();
$('ul').append(cb);
}
});
Demo: http://jsfiddle.net/ZF7bD/7/

chekbox click creating an issue?

<ul class="sorting" id="filter_by">
<li><input checked="checked" type="checkbox" id="foobar" /><label for="chk1">foobar</label></li>
<li><input checked="checked" type="checkbox" id="foobaz"/><label for="chk2">baz</label></li>
<li><input checked="checked" type="checkbox" id="foofoo"/><label for="chk3">foo</label></li>
</ul>
I want to know how many checkbox are checked. SO I wrote:
$("#filter_by").change(function() {
alert('hi');
var len_checked = $("#filter_by > li > input:checked").length;
});
But Every Time It call for twice. So, alert run two time. Suppose at first all three are checked
Now I unchecked one element. Then alert run twice. I could find the reason?
You should bind the .change handler to the checkboxes, and not the UL:
$("#filter_by :checkbox").change(function() {
alert('hi');
var len_checked = $("#filter_by > li > input:checked").length;
});
You can try it here.
That said, I cannot duplicate what you have reported, at least not on Chrome with the code you posted, so something else could be causing this. Is there any relevant detail you have left out?

Categories