I am using the Bootstrap Tree to create a nested checkbox list(http://jhfrench.github.io/bootstrap-tree/docs/example.html), however, I want to make the checked item highlighted, as well as have the children highlighted when the parent is selected. I've got it kind of working, but now when the parent is selected, the background-color on the individual child won't toggle when unchecked. i.e. it only toggles when its parent is not selected.
See jsfiddle: https://jsfiddle.net/tqku87ym/7/
$(function checkbox() {
$("input[type='checkbox']").change(function () {
$(this).siblings('ul')
.find("input[type='checkbox']")
.prop('checked', this.checked);
$(this).parent('li').toggleClass("highlight");
});
});
I've edited your code in a new fiddle: https://jsfiddle.net/pjrzbbea/.
I've introduced a separated highlight class for the children, which also has a background color overlapping the parent's background color. The JS part now also removes the highlight class from the child elements, if the parent element gets highlighted - so the children get resetted correctly.
$(function checkbox() {
$("input[type='checkbox']").change(function () {
var highlightChildClass = 'highlightChild';
$(this).siblings('ul')
.find('li')
.removeClass(highlightChildClass)
.find("input[type='checkbox']")
.prop('checked', this.checked);
var highlightClass = 'highlight';
if ($(this).closest('ul[role="group"]').length > 0) {
highlightClass = highlightChildClass;
}
$(this).parent('li').toggleClass(highlightClass);
});
});
You can't toggle the class if the way to change the background can come from multiple sources. When you change the parent, you'll have to clean the children. Here is the sample code modified. https://jsfiddle.net/wgpahro4/
$(function checkbox() {
$("input[type='checkbox']").change(function () {
$(this).siblings('ul')
.find("input[type='checkbox']")
.prop('checked', this.checked);
//ADDED CODE STARTS HERE!!!!!!!!!!!
//Clean up children
if($(this).parent().hasClass("parent_li")){
if(!this.checked){
$(this).siblings("ul").find("li").removeClass("highlight");
}
}
//ADDED CODE ENDS HERE!!!!!
$(this).parent('li').toggleClass("highlight");
});
});
If you want each child checkbox to highlight while the parent checkbox can still override, something like this will work:
$(function checkbox() {
$("input[type='checkbox']").change(function () {
if ($(this).siblings('ul').length > 0) {
var children = $(this).siblings('ul').find('input');
children.prop('checked', this.checked).change();
}
else {
var item = $(this).parent('li');
this.checked ? item.addClass('highlight') : item.removeClass('highlight');
}
});
});
Related
I'm trying to toggle all checkboxes on a table and my code works but has a few issues and I don't find how to get ride of them. So here is the code:
$(function () {
$('#toggleCheckbox').on('click', function () {
var $toggle = $(this).is(':checked');
$("#codigoArancelarioBody").find("input:checkbox").click();
});
});
Take a look at this Fiddle I setup for testing and do this tests:
Mark the first checkbox (the one at table heading level) the rest of them inside #codigoArancelarioBody get checked and this is right
Mark first the checkbox at the first row (the only at table body level) and then mark the toggleAll you will see how things goes wrong since if I check the toggleAll them all should remain checked and that's the wrong part on my code
How I can fix this? Also I'll like to add a class 'removedAlert' to those TR I mark, how?
You need two click event handlers, one for the check/uncheck all box and one for the other ones
JS
$('#toggleCheckbox').on('click', function () {
var $toggle = $(this).is(':checked');
$("#codigoArancelarioBody").find("input:checkbox").prop("checked", $toggle);
});
$("#codigoArancelarioBody input:checkbox").on('click', function () {
if (!$(this).is(':checked')) {
$('#toggleCheckbox').prop("checked", false);
} else if ($("#codigoArancelarioBody input:checkbox").length == $("#codigoArancelarioBody input:checkbox:checked").length) {
$('#toggleCheckbox').prop("checked", true);
}
});
DEMO
since the same code will be applied in a lot of places on my code and
to avoid DRY, I'll like to pass the selector as a parameter in all
your code solution could you edit your post to achieve this?
$toggleCheckBox = $('#toggleCheckbox');
$checkBoxTbody = $("#codigoArancelarioBody");
$toggleCheckBox.on('click', function () {
var $toggle = $(this).is(':checked');
$checkBoxTbody.find("input:checkbox").prop("checked", $toggle);
});
$checkBoxTbody.find("input:checkbox").on('click', function () {
if (!$(this).is(':checked')) {
$toggleCheckBox.prop("checked", false);
} else if ($checkBoxTbody.find("input:checkbox").length == $checkBoxTbody.find("input:checkbox:checked").length) {
$toggleCheckBox.prop("checked", true);
}
});
DEMO
If you don't need the "click" event for something else you can do this:
$(function () {
$('#toggleCheckbox').on('change', function () {
var toggle = $(this).is(':checked');
$("#codigoArancelarioBody").find("input:checkbox").prop('checked', toggle ).closest('tr').addClass('removedAlert');
});
});
The code is actually executing what you told it to do, i.e. every time I click the checkbox on top click to other checkboxes. This way if a box is checked it will uncheck itself, because it won't mind if the top is checked or not.
What you really want is "when I check the box on top, check all the others, when I uncheck it, then uncheck all the others", which is sort of different as you see.
Try this:
$(function () {
// best practice: always store the selectors you access multiple times
var checkboxes = $("#codigoArancelarioBody").find("input:checkbox"),
toggleAll = $('#toggleCheckbox');
toggleAll.on('click', function () {
// is the top checkbox checked? return true, is it unchecked? Then return false.
var $toggle = $(this).is(':checked');
// .prop('checked', true) makes it checked, .prop('checked', false) makes it unchecked
checkboxes.prop('checked', $toggle);
});
});
see: http://jsfiddle.net/gleezer/nnfg80x1/3/
On my table clicking the row will highlight it, and should also check the corresponding checkbox. Furthermore if the checkall checkbox is checked, all rows should be highlighted. If the checks remove, the highlights should be removed. I cannot give ids and would like to do this dynamically with .find() or .closest() or something similar. Any ideas? Thanks in advance! http://jsfiddle.net/7vLdxddr/3/
jQuery
$('table').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
}
else {
$('tr.selected').removeClass('selected');
$(this).addClass('selected');
}
});
$("input[type=checkbox].checkall").on("click", function () {
$(this).parents('.table:eq(0)').find('input:checkbox').prop('checked', this.checked);
});
Use an instance of this (which refers to the row clicked on) and find
$(this).find(":checkbox").prop("checked", true);
http://jsfiddle.net/2wpmxdp0/1/
Use the checked property to add and remove class.
$('table').on('click', 'tr', function () {
var $this = $(this),
$rowCheckbox = $this.find(":checkbox");
// Add and remove class based on the class on the row
// You can always use this as the event is bound to the
// row which is clicked. So can use the this context
if ($this.hasClass('selected')) {
$this.removeClass('selected');
// Uncheck the checkbox if already selected
$rowCheckbox.prop('checked', false);
} else {
$this.addClass('selected');
$rowCheckbox.prop('checked', true);
}
});
// No need to use the checkbox selector again
// You have already added the class to it
$(".checkall").on("click", function (e) {
// To make sure the row event is not fired
// due to event bubbling
e.stopPropagation();
var isChecked = this.checked,
$table = $(this).parents('.table:eq(0)'),
$rows = $table.find('tr');
$table.find('input:checkbox').prop('checked', isChecked);
this.checked ? $rows.addClass('selected') : $rows.removeClass('selected');
});
Updated Fiddle
I have a list of checkbox and want to select the only one check box and add the class for the checkbox input and select another checkbox remove that class from the existing checkbox
$('input.myclass').click(function ()
{
var id = $(this).attr('id').replace('image-','');
$('input.myclass:checked').not(this).removeAttr('checked');
var sFilter = "";
$('input.myclass[type=checkbox]').each(function () {
sFilter = sFilter + (this.checked ? $(this).val() : "");
});
check();
});
function check(){
var a = $('input:checkbox[name=cover_image]:checked').val();
alert(a);
}
I want to select only one checkbox and class for the checked checkbox if that checkbox not checked then remove the class for that
If you really want to use checkboxes(and not radio buttons) for some reason, do something like this:
$('input:checkbox').on('click', function () {
$('input.selected').removeClass('selected').prop('checked', false);
$('input:checked').addClass('selected');
});
Edit: Removing the attribute works, but property manipulation is a slighty better way of doing it(as suggested by RobG)
For your purpose first remove classes from all checkbox and unchecked them and then add class to clicked checkbox and checked it as below
$("input[type='checkbox']").on('click', function () {
$("input[type='checkbox']").removeClass('selected').attr('checked', false);
$(this).addClass('selected').attr('checked', true);
});
Check this Fiddle for your question
you may use on() to listen the changes on group of checkboxes.
var $checkBoxes = $(":checkbox").on("change", function () { // Here listening the changes on checkbox using on()
$checkBoxes.removeClass("change").attr("checked", false); // remove the class from existing Checkbox
$(this).addClass("change").attr("checked", true); // adding the class for the currenly checked checkbox
});
working FIDDLE is here
The Fiddle: http://jsfiddle.net/bscn3/
Scenario:
I want to use nested toggles inside tabbed containers, as in the fiddle.
My Issue:
When I click on Main Toggle ("Toggle 1") or ("Toggle 2"), the inner contents display.
But it closes if I click on anything inside. For Eg. If I click on Toggle 2, and if I click on Tab 1 -> Nested Toggle 1, Toggle 2 itself closes.
I want it to remain open.
My Guess:
The JQuery working closes the toggle if anything related to the Toggle (Even text content) is clicked.
My Need:
I want the Toggle to close only if those rectangular headers are clicked.
Also, if you can help clean up the code in such a way, that I don't need to write separate JS to make inner nested Toggles work independently of its parent or children toggles, it would great.
Currently I have two Toggle JS Functions written for the two toggles in example.
//TOGGLE
$('.toggle-view li').click(function () {
var text = $(this).children('.t');
if (text.is(':hidden')) {
text.slideDown('fast');
$(this).children('.toggle').addClass('tactive');
} else {
text.slideUp('fast');
$(this).children('.toggle').removeClass('tactive');
}
});
//TOGGLE L2
$('.toggle-view2 li').click(function () {
var text2 = $(this).children('.t2');
if (text2.is(':hidden')) {
text2.slideDown('fast');
$(this).children('.toggle2').addClass('tactive2');
} else {
text2.slideUp('fast');
$(this).children('.toggle2').removeClass('tactive2');
}
});
P.S. I haven't written the JS Code, I am using someone's template.
Thanks! :)
Seems like a pretty simple solution...
It's happening because the toggle currently activates whenever you click anythin inside of the li element (which includes the other toggle elements: .toggle2).
The solution therefore is to make it only activate the toggle when the .toggle/h6 element is clicked and change $(this).children(...) to $(this).siblings(...)
You can use the following as things are (same changes in TOGGLE and TOGGLE L2):
//TOGGLE
$('.toggle-view li .toggle').click(function () { // Changed selector
var text = $(this).siblings('.t'); // Changed to .siblings(...)
if (text.is(':hidden')) {
text.slideDown('fast');
$(this).addClass('tactive'); // Removed .children(...)
} else {
text.slideUp('fast');
$(this).removeClass('tactive'); // Removed .children(...)
}
});
//TOGGLE L2
$('.toggle-view2 li .toggle2').click(function () {
var text2 = $(this).siblings('.t2');
if (text2.is(':hidden')) {
text2.slideDown('fast');
$(this).addClass('tactive2');
} else {
text2.slideUp('fast');
$(this).removeClass('tactive2');
}
});
OR
Just use the first section...
//TOGGLE
$('.toggle-view li .toggle').click(function () {
var text = $(this).siblings('.t');
if (text.is(':hidden')) {
text.slideDown('fast');
$(this).addClass('tactive');
} else {
text.slideUp('fast');
$(this).removeClass('tactive');
}
});
and rename all of the .t2, .toggle2 etc. in your html to the same as the first one (i.e. .t2 becomes .t)
use event.stopPropagation()
i have updated jsfiddle
$('.toggle-view2 li').click(function (event) {
event.stopPropagation();
var text2 = $(this).children('.t2');
if (text2.is(':hidden')) {
text2.slideDown('fast');
$(this).children('.toggle2').addClass('tactive2');
} else {
text2.slideUp('fast');
$(this).children('.toggle2').removeClass('tactive2');
}
});
Currently I have two tables
I have select-all functions on the top left checkboxes, but clicking on one select-all highlights all checkboxes in BOTH tables, whereas I only want all boxes to be selected in the specific 'check-all' clicked.
Also, when I do select all and click one of the directional buttons < or >, it drags all the rows fine but drags the headers with it as shown here:
My JQuery is quite simple at the moment but I'm obviously missing out on something -
$('#select-all').click(function (event) {
if (this.checked) {
// Iterate each checkbox
$(':checkbox').each(function () {
this.checked = true;
});
}
else
// Iterate each checkbox
$(':checkbox').each(function () {
this.checked = false;
});
});
Where 'select-all' is the id of the select-all checkbox in the 'tarifs de quittancement'.
Any help is appreciated
EDIT
My JQuery for the > button code is as follows :
$("#move-to-1").on("click", function () {
var selected = $("#table2").find("input:checked");
selected.each(function (idx, elem) {
$(elem).closest("tr").detach().appendTo($("#table1 tbody"));
});
});
This works fine to move all from one table to the other, but I don't want the row containing the select-all checkbox/table headers to move with the rest of the row data. How can this be done?
Thanks again.
Further Edit
Now it's all sorted, except for a small bug where selecting one checkbox row (not select-all) and moving it < or > results in ALL rows being moved.
JQuery in use:
$('#move-to-1').on('click', function () {
var selected = $('#table2').find('input:checked');
selected.each(function (idx, elem) {
$(elem).closest('tbody').find('tr').detach().appendTo($("#table1 tbody"));
$('input[type=checkbox]').attr('checked', false);
});
});
$('#select-all').click(function (event) {
$(this).closest('table').find(':checkbox').prop('checked', this.checked);
});
You only need to modify the checkboxes inside the current table. Since you haven't shown your markup it is extremely hard to guess how the proper selector might look or whether you are using tables at all but try like this:
$('#select-all').click(function (event) {
$(this).closest('table').find(':checkbox').prop('checked', this.checked);
});
UPDATE:
To address your second question, assuming you have separated the headers from the body inside those tables using the <thead> and <tbody> sections which is the correct way, you could adapt your selector:
$('#move-to-1').on('click', function () {
var selected = $('#table2 tbody').find('input:checked');
selected.each(function (idx, elem) {
$(elem).closest('tr').detach().appendTo($("#table1 tbody"));
});
});
$('#select-all').click(function (event) {
// mention the table
var table = $('selector_to_your_table');
if (this.checked) {
// Iterate each checkbox
table.find(':checkbox').each(function () {
this.checked = true;
});
}
else
// Iterate each checkbox
table.find(':checkbox').each(function () {
this.checked = false;
});
});
Note
In latest version of jQuery :checkbox is deprecated. See here..
Instead of :checkbox use input[type=checkbox].
Instead of:
$(':checkbox').each(function () {
this.checked = true;
});
Do:
$('some_sort_of_selector :checkbox').attr('checked', true);
You don't need that each() loop - jQuery does it automatically. You need some kind of selector to limit which checkboxes are changed.
I notice you have #select-all - and yet you say you have two select-all checkboxes. You can't do that. ID's must be unique.