Checkbox rows - slideUp complete issue - javascript

I have multiple divs of 3 checkboxes – each div has a show/hide button (jQuery slideUp) that hides the 'ul.task-list' to display the H2 heading.
<div class="row" id="row-0">
<button class="toggle">Toggle</button>
<h2>Row 0</h2>
<ul class="task-list">
<li><input type="checkbox" id="task-0-0" class="task" value="0" /></li>
<li><input type="checkbox" id="task-0-1" class="task" value="1" /></li>
<li><input type="checkbox" id="task-0-2" class="task" value="2" /></li>
</ul>
</div>
<div class="row" id="row-1">
<button class="toggle">Toggle</button>
<h2>Row 1</h2>
<ul class="task-list">
<li><input type="checkbox" id="task-1-0" class="task" value="0" /></li>
<li><input type="checkbox" id="task-1-1" class="task" value="1" /></li>
<li><input type="checkbox" id="task-1-2" class="task" value="2" /></li>
</ul>
</div>
I call a 'checkTotal' function, and if everything in the row is checked, add the class of "complete" and slideUp the UL.
let sections = $('.row').map(function() { return this.id }).get(); // gets id of row
const tasksTotal = 3; // the total checkboxes in each row
function checkTotal() {
sections.forEach(function(i) { // loops section IDs
let total = $('#'+i+' input:checked').length; // checked in row
total == tasksTotal ? ($('#'+i).addClass('complete'), $('#'+i+' .task-list').slideUp()) : ($('#'+i).removeClass('complete')); // add class & hide row
});
}
checkTotal();
The issue is, if I click to show row 0 (after complete) and then check anything in row 1 – it will automatically slide row 0 up again – as complete remains true (all items are checked).
I just can't figure out how to separate these, so they act independently and without looping through again.

You can passed this under your checkTotal() function which will be used to check only the checkbox which is check by user.Then we can use this to get closest ul and loop through only that part where checkbox is located and then to we need to find checkbox length which are checked we can get that using elem.find("input:checked").length.
Demo Code :
jQuery(function() {
jQuery('.toggle').on('click', function() {
jQuery(this).parent().siblings('.task-list').slideToggle();
});
const tasksTotal = 3; // the total checkboxes in each row
function checkTotal(el) {
//find closest ul
var elem = jQuery(el).closest(".task-list");
//loop through it
elem.each(function() {
//get total count of checked input
let total = elem.find("input:checked").length;
console.log(total)
//apply the same to particular ul
total == tasksTotal ? (elem.addClass('complete'), elem.slideUp()) : (elem.removeClass('complete'));
});
}
$('.task').change(function() {
checkTotal(this);//passed only the checkbox clicked
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row" id="row-0">
<div class="options">
<h2>Row 0</h2>
<button class="toggle">Toggle</button>
</div>
<ul class="task-list" data="abd">
<li><input type="checkbox" id="task-0-0" class="task" value="0" /> <label for="task-0-0"> Item 0</label></li>
<li><input type="checkbox" id="task-0-1" class="task" value="1" /> <label for="task-0-1"> Item 1</label></li>
<li><input type="checkbox" id="task-0-2" class="task" value="2" /> <label for="task-0-2"> Item 2</label></li>
</ul>
</div>
<div class="row" id="row-1">
<div class="options">
<h2>Row 1</h2>
<button class="toggle">Toggle</button>
</div>
<ul class="task-list">
<li><input type="checkbox" id="task-1-0" class="task" value="0" /> <label for="task-1-0"> Item 0</label></li>
<li><input type="checkbox" id="task-1-1" class="task" value="1" /> <label for="task-1-1"> Item 1</label></li>
<li><input type="checkbox" id="task-1-2" class="task" value="2" /> <label for="task-1-2"> Item 2</label></li>
</ul>
</div>

Related

How to get values from <li> elements?

I have three different sections for filter and a button and i want to use filter on these sections, I just want to know that
how can i get value of these sections ( inside ul li)
<div id="new-items" class="dropdown">
New Items
<ul class="">
<li><span>New bestsellers</span></li>
<li><span>New releases</span></li>
</ul>
</div>
<div id="buy" class="dropdown">
Buy Now
<ul class="">
<li><span>Wallet</span></li>
<li><span>Website</span></li>
</ul>
</div>
<div id="sort-by" class="dropdown">
Sort By
<ul class="">
<li><span>Low To High Price</span></li>
<li><span>High To Low Price</span></li>
<li><span>View</span></li>
<li><span>View</span></li>
<li><span>Rating</span></li>
<li><span>Sale</span></li>
<li><span>Date</span></li>
</ul>
</div>
<button class="sc-button style letter style-2 filter"><span>Filter</span> </button>
This is how your HTML now renders
You need to convert the <li> to radio buttons.
For example, the sort choices.
<input type="radio" name="sort" value="1"> Low To High Price<br>
<input type="radio" name="sort" value="2"> High To Low Price<br>
<input type="radio" name="sort" value="3"> View<br>
<input type="radio" name="sort" value="4"> View<br>
<input type="radio" name="sort" value="5"> Rating<br>
<input type="radio" name="sort" value="6"> Sale<br>
<input type="radio" name="sort" value="7"> Date<br>
The above looks like this:
It may not be jQuery but it is simple enough in vanilla Javascript. The comments tell you what is happening.
// a global variable to be populated when specific SPAN elements are clicked.
let selection=false;
// bind a delegated listener to the document or suitable ancestor
document.addEventListener('click',e=>{
// If the "click" is on a SPAN of interest, populate the global variable
if( e.target.tagName=='SPAN' && e.target.parentNode.tagName=='LI' ){
selection=e.target;
}
// if the button is clicked, filter ...
if( e.target.tagName=='SPAN' && e.target.parentNode.tagName=='BUTTON' && selection ){
alert(selection.textContent)
}
});
<div id="new-items" class="dropdown">
New Items
<ul class="">
<li><span>New bestsellers</span></li>
<li><span>New releases</span></li>
</ul>
</div>
<div id="buy" class="dropdown">
Buy Now
<ul class="">
<li><span>Wallet</span></li>
<li><span>Website</span></li>
</ul>
</div>
<div id="sort-by" class="dropdown">
Sort By
<ul class="">
<li><span>Low To High Price</span></li>
<li><span>High To Low Price</span></li>
<li><span>View</span></li>
<li><span>View</span></li>
<li><span>Rating</span></li>
<li><span>Sale</span></li>
<li><span>Date</span></li>
</ul>
</div>
<button class="sc-button style letter style-2 filter"><span>Filter</span></button>
get all the li elements inside div, then loop the array
example for the first div:
const newItems = document.querySelectorAll('#new-items li');
newItems.forEach(function(item) {
console.log(item.innerText);
})

How to add checkboxes values to textarea field

I have textarea field and 3 groups of checkboxes. User can individually select any checkbox and checkbox value will be added to textarea field. But how to include "Select all" functionality to select all checkboxes in group? I created "Select all" function, but after selection values are not added to textarea field.
// Add checkbox value to text field
$checks = $("ul li :checkbox");
$checks.on("change", function() {
var string = $checks.filter(":checked").map(function(i,v){
return this.value;
}).get().join(",");
$("#results").val( "checked:" + string);
});
// Select all checkboxes in the group
jQuery(function($){
$('#allg1').click(function () { $('.group1 li input').not(this).prop('checked', this.checked);});
$('#allg2').click(function () { $('.group2 li input').not(this).prop('checked', this.checked);});
$('#allg3').click(function () { $('.group3 li input').not(this).prop('checked', this.checked);});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="results" rows="2" cols="60"> </textarea>
<ul class="group1">
<input type="checkbox" id="allg1" name="allg1"><label for="allg1">Select all from group G1</label>
<li><input type="checkbox" value="G101"></li>
<li><input type="checkbox" value="G102"></li>
<li><input type="checkbox" value="G103"></li>
</ul>
<ul class="group2">
<input type="checkbox" id="allg2" name="allg2"><label for="allg2">Select all from group G2</label>
<li><input type="checkbox" value="G201"></li>
<li><input type="checkbox" value="G202"></li>
<li><input type="checkbox" value="G203"></li>
</ul>
<ul class="group3">
<input type="checkbox" id="allg3" name="allg3"><label for="allg3">Select all from group G3</label>
<li><input type="checkbox" value="G301"></li>
<li><input type="checkbox" value="G302"></li>
<li><input type="checkbox" value="G303"></li>
</ul>
To achieve this you can trigger() the change event manually on the checkboxes when the 'Select all' is toggled. Your normal event handler will then run which updates the text in the textbox.
Also note that you can DRY up the JS controlling the 'Select all' boxes by using common class attributes on them.
jQuery($ => {
// Add checkbox value to text field
let $checks = $("ul li :checkbox").on("change", function() {
let string = $checks.filter(":checked").map((i, el) => el.value).get().join(",");
$("#results").val(string && "checked:" + string);
});
// Select all checkboxes in the group
$('.all').click(e => {
$(e.target).closest('.group').find('li input').not(e.target).prop('checked', e.target.checked).trigger('change');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="results" rows="2" cols="60"> </textarea>
<ul class="group">
<label><input type="checkbox" class="all" name="allg1">Select all from group G1</label>
<li><input type="checkbox" value="G101"></li>
<li><input type="checkbox" value="G102"></li>
<li><input type="checkbox" value="G103"></li>
</ul>
<ul class="group">
<label><input type="checkbox" class="all" name="allg2">Select all from group G2</label>
<li><input type="checkbox" value="G201"></li>
<li><input type="checkbox" value="G202"></li>
<li><input type="checkbox" value="G203"></li>
</ul>
<ul class="group">
<label><input type="checkbox" class="all" name="allg3">Select all from group G3</label>
<li><input type="checkbox" value="G301"></li>
<li><input type="checkbox" value="G302"></li>
<li><input type="checkbox" value="G303"></li>
</ul>

HTML change radio button background

I would like the background color to remain the same foreach <ul> as lightgray.
Currently when clicking the radio button, it will change the ul background wrongly. I dont know how to make the jquery script loop thru all the ul available, I would really appreciate it if the script can be small, as this concept will be applied to 100+ ul
$(document).ready(function() {
$("ul.options-list li").on("click",function() {
if($(this).find('input[type="radio"]').is(':checked')) {
$('ul.options-list li').removeClass('change_color');
$(this).addClass('change_color');
}
});
});
ul.options-list li.change_color{
background-color: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
Q1
<ul class="options-list">
<li>
<input type="radio" name="r1" id="1" value="1" data-toggle="radio">O1
</li>
<li>
<input type="radio" name="r1" id="2" value="2" data-toggle="radio">O2
</li>
</ul>
</div>
<div>
Q2
<ul class="options-list">
<li>
<input type="radio" name="r2" id="3" value="3" data-toggle="radio">A1
</li>
<li>
<input type="radio" name="r2" id="4" value="4" data-toggle="radio">A2
</li>
</ul>
</div>
You can loop through your ul li using each loop then use $(this) to check if the radio is checked depending on this add or remove your class.
Demo Code :
$(document).ready(function() {
$("ul.options-list li").on("click", function() {
//loop through ul li
$("ul.options-list li").each(function() {
if ($(this).find('input[type="radio"]').is(':checked')) {
$(this).addClass('change_color');//add change_Color
} else {
$(this).removeClass('change_color');//remove same
}
})
});
});
ul.options-list li.change_color {
background-color: lightgray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
Q1
<ul class="options-list">
<li>
<input type="radio" name="r1" id="1" value="1" data-toggle="radio">O1
</li>
<li>
<input type="radio" name="r1" id="2" value="2" data-toggle="radio">O2
</li>
</ul>
</div>
<div>
Q2
<ul class="options-list">
<li>
<input type="radio" name="r2" id="3" value="3" data-toggle="radio">A1
</li>
<li>
<input type="radio" name="r2" id="4" value="4" data-toggle="radio">A2
</li>
</ul>
</div>
I am not great with javascript.
but maybe give all your radio buttons the same class and add something like this
document.getElementByClass("myCheck").checked = true;
and then addClass('change_color') to those selected.
https://www.w3schools.com/jsref/prop_checkbox_checked.asp

jquery to iterate through list items with nested inputs

I have inputs nested inside of anchors nested inside of list items. I'd like to use jquery to iterate through the list items, and if an item was selected display the values in a text field. I'm close, I'm down to the input control, but the "if (checked)" statement is not working.
Can somebody please tell me what I'm doing wrong? :(
function ddDistrictChanged() {
var txt = "nothing selected";
var $inp = $('#ddDistrict').find('input');
$inp.each(function (index) {
$('#txtHere').text($(this).children('li'));
if ($(this).checked) {
txt = txt + ', ' + $(this).text();
}
$('#txtHere2').text(txt);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ddDistrict" class="dropdown-menu">
<li><input name="selCol" type="checkbox" value="1"> District 1 (Porter)</li>
<li><input name="selCol" type="checkbox" value="2"> District 2 (Jones Jr.)</li>
<li><input name="selCol" type="checkbox" value="3"> District 3 (Horne)</li>
<li><input name="selCol" type="checkbox" value="4"> District 4 (Haddaway)</li>
<li><input name="selCol" type="checkbox" value="5"> District 5 (Duncan)</li>
<li><input name="selCol" type="checkbox" value="6"> District 6 (Willner)</li>
<li><input name="selCol" type="checkbox" value="7"> District 7 (Brady)</li>
<li><button type="button" class="btn btn-default btn-sm btn-info center-block" onclick="ddDistrictChanged();">Submit</button></li>
</ul>
<div id="txtHere"></div>
<div id="txtHere2"></div>
Would make it cleaner if you wrapped the text in an element like <span>
<li><a ><input/><span> District 1 (Porter)</span></a></li>
Next can use :checked pseudo selector to select only checked inputs
function ddDistrictChanged() {
var txt = "nothing selected";
var $items = $('#ddDistrict').find('li has(input:checked)');
if ($items.length) {
txt = $items.map(function() {
return $(this).find('span').text()
}).get().join(', ');
}
$('#txtHere2').text(txt);
}
Working JSFiddle DEMO
To start with, lets refactor your HTML to make it a bit easier to interact with when using JavaScript/jQuery. I have opted to use labels with your inputs instead of <a> tags.
<ul class="ddDistrict dropdown-menu">
<li>
<input type="checkbox" id="cbox1" value="1" checked>
<label for="cbox1" class="small underlineText_No">District 1 (Porter)
</label>
</li>
<li>
<input type="checkbox" id="cbox2" value="2">
<label for="cbox2" class="small underlineText_No">District 2 (Jones Jr)
</label>
</li>
<li>
<input type="checkbox" id="cbox3" value="3">
<label for="cbox3" class="small underlineText_No">District 3 (Horne)
</label>
</li>
<li>
<input type="checkbox" id="cbox4" value="4">
<label for="cbox4" class="small underlineText_No">District 4 (Haddaway)
</label>
</li>
<li>
<input type="checkbox" id="cbox5" value="5">
<label for="cbox5" class="small underlineText_No">District 5 (Duncan)
</label>
</li>
<li>
<input type="checkbox" id="cbox6" value="6">
<label for="cbox6" class="small underlineText_No">District 6 (Willner)
</label>
</li>
<li>
<input type="checkbox" id="cbox7" value="7">
<label for="cbox7" class="small underlineText_No">District 7 (Brady)
</label>
</li>
<li>
<button type="button" class="btn btn-default btn-sm btn-info center-block" onclick="ddDistrictChanged();">Submit</button>
</li>
</ul>
<div class="txtHere"></div>
I then created some basic JavaScript/jQuery to check if any checkboxes have been checked on load and update the DOM according to what has been checked, and when they are checked.
var $inputs = $('.ddDistrict input');
var $outputWrapper = $('.txtHere');
// Check for boxes that have already been checked and
// append their labels to the DOM.
$inputs.each(function() {
var currentLabel = $(this).next('label').text();
var currentID = $(this).attr('id');
if (this.checked) {
var outputText = $('<p></p>').addClass(currentID).text(currentLabel);
$outputWrapper.append(outputText);
}
});
// This event handler will watch for any changes to the
// checkboxes and will append the value of their labels
// to the DOM on change.
$inputs.change(function() {
var currentLabel = $(this).next('label').text();
var currentID = $(this).attr('id');
if (this.checked) {
var outputText = $('<p></p>').addClass(currentID).text(currentLabel);
$outputWrapper.append(outputText);
} else {
$('.' + currentID).remove();
}
});
It's all relatively simple stuff and the code can be refactored to make it more DRY, but this should definitely put you in the right direction. Let me know if you have any questions.

Jquery - Enable/disable multiple checkboxes in multiple lists

I have three lists in my page (ul.list1, ul.list2, ul.list3) and each li of every list has checkboxes. From the beginning I want to have all checkboxes disabled except from the ones in .list1.
The thought is that I have to select THREE .list1-checkboxes, then only ONE in .list2 and then AUTOCHECK the .list3-checkbox.
To be more specific if I click three .list1-checkboxes I want to disable the rest of the .list1-checkboxes and enable .list2-checkboxes. But if I uncheck one of the .list1-checkboxes I want to enable the rest .list1-checkboxes again and disable .list2-checkboxes whether I had already clicked on them or not.
Now if I select one .list2-checkbox I want the rest of the .list2-checkboxes to be disabled and in .list3 enable and autocheck the only one checkbox there is. If I uncheck the .list2-checkbox I want the the .list2-checkboxes to be enabled again and .list3-checkbox to be unchecked and disabled.
The HTML is something like that:
<div>
<ul class="list1">
<li><input type="checkbox" /><label>list1-item1</label></li>
<li><input type="checkbox" /><label>list1-item2</label></li>
<li><input type="checkbox" /><label>list1-item3</label></li>
<li><input type="checkbox" /><label>list1-item4</label></li>
<li><input type="checkbox" /><label>list1-item5</label></li>
</ul>
</div>
<div>
<ul class="list2">
<li><input type="checkbox" /><label>list2-item1</label></li>
<li><input type="checkbox" /><label>list2-item2</label></li>
<li><input type="checkbox" /><label>list2-item3</label></li>
<li><input type="checkbox" /><label>list2-item4</label></li>
<li><input type="checkbox" /><label>list2-item5</label></li>
<li><input type="checkbox" /><label>list2-item6</label></li>
<li><input type="checkbox" /><label>list2-item7</label></li>
<li><input type="checkbox" /><label>list2-item8</label></li>
</ul>
<div>
</div>
<ul class="list3">
<li><input type="checkbox" /><label>list3-item1</label></li>
</ul>
</div>
Your requirements can be acheived through event handlers. You can find a list of events in this page : HTML DOM Events. And if you want to use jQuery to attach event handlers, you can read on() | jQuery API.
// Code goes here
$(function() {
var list1 = $('.list1 > li > input[type="checkbox"]');
var list2 = $('.list2 > li > input[type="checkbox"]');
var list3 = $('.list3 > li > input[type="checkbox"]');
list1.on('change', function(event) {
var numList1 = $(list1).filter(':checked').length;
if(numList1 >= 3) {
$(list1).filter(':not(:checked)').prop('disabled', true);
$(list2).prop('disabled', false);
} else {
$(list1).prop('disabled', false);
$(list2).prop('checked', false).prop('disabled', true);
$(list3).prop('checked', false).prop('disabled', true);
}
});
list2.on('change', function(event) {
var numList2 = $(list2).filter(':checked').length;
if(numList2 >=1) {
$(list2).filter(':not(:checked)').prop('disabled', true);
$(list3).prop('checked', true).prop('disabled', false);
}
else {
$(list2).prop('disabled', false);
$(list3).prop('checked', false).prop('disabled', true);
}
});
});
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#2.2.0" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div>
<ul class="list1">
<li>
<input type="checkbox" />
<label>list1-item1</label>
</li>
<li>
<input type="checkbox" />
<label>list1-item2</label>
</li>
<li>
<input type="checkbox" />
<label>list1-item3</label>
</li>
<li>
<input type="checkbox" />
<label>list1-item4</label>
</li>
<li>
<input type="checkbox" />
<label>list1-item5</label>
</li>
</ul>
</div>
<div>
<ul class="list2">
<li>
<input type="checkbox" disabled/>
<label>list2-item1</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item2</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item3</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item4</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item5</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item6</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item7</label>
</li>
<li>
<input type="checkbox" disabled/>
<label>list2-item8</label>
</li>
</ul>
<div></div>
<ul class="list3">
<li>
<input type="checkbox" disabled/>
<label>list3-item1</label>
</li>
</ul>
</div>
</body>
</html>

Categories