Link Checkboxes with Parent/Child Relationship without jQuery - javascript

I'm not sure how to explain it. Hopefully my code is self-evident. I am fairly new to javascript.
<div>
<input type="checkbox" id="checkBox1" onclick="toggleCheckBox(this)">Check Box 1</input>
<div>
<input type="checkbox" id="checkBox2">Check Box 2</input>
</div>
</div>
function toggleCheckBox(checkBox1) {
// I've also tried 'checkBox1.parent' and 'checkBox1.parentElement'
var cb2 = checkBox1.parentNode.getElementByTagName('div').getElementByTagName('input');
if (checkBox1.checked == true) {
cb2.checked = true;
} else {
cb2.checked = false;
};
};
I keep getting checkBox1.parent is undefined.
Edit:
final desired out come:
<div id="a">
<input type="checkbox" onclick="toggleCheckBox(this)">Check Box 1</input>
<div>
<input type="checkbox">Check Box 2</input>
<input type="checkbox">Check Box 3</input>
</div>
</div>
<div id="b">
<input type="checkbox" onclick="toggleCheckBox(this)">Check Box 1</input>
<div>
<input type="checkbox">Check Box 2</input>
<input type="checkbox">Check Box 3</input>
</div>
</div>
and so on.
Edit: Parent Indeterminate
I got the parent to go to indeterminate, but it won't leave unless you click it.
/* clicked child checkbox */
var parentId = clickedBox.dataset.parent;
var checkedTrue = false;
var checkedFalse = false;
var checkState = clickedBox.checked;
Array.prototype.slice.call(allCheckboxes).forEach(function(checkbox) {
/* search checkboxes having same data-parent as clickedBox and is not checked */
if (parentId === checkbox.dataset.parent && !checkbox.checked) {
checkedFalse = true;
checkState = false;
return false;
} else if (parentId === checkbox.dataset.parent && checkbox.checked) {
checkedTrue = true;
return false;
}
});
/* search parent checkbox of clickedBox */
Array.prototype.slice.call(allCheckboxes).forEach(function(parentBox) {
if (parentBox.id === parentId) {
if (checkedTrue === true && checkedFalse === true) {
parentBox.indeterminate = true;
return false;
} else {
parentBox.checked = checkState;
return false;
}
}
});

In-case use of HTML5 data-* is not an constraint, this solution works with most of updated browsers including IE 11. Here, I am using data-parent attribute(having value same as id of parent) to link checkbox with its parent checkbox. Value -1 for data-parent denotes that there is no parent for the given checkbox.
let allCheckboxes;
/* checkbox click handler */
let toggleCheck = function(e) {
e.stopPropagation();
var clicked = this;
/* clicked ones is the parent */
if ('-1' === clicked.dataset.parent) {
/* search child checkboxes having data-parent=id of clicked ones */
Array.prototype.slice.call(allCheckboxes).forEach(function(c) {
if (c.dataset.parent === clicked.id) {
/* set checked state same as clicked ones */
c.checked = clicked.checked;
}
});
} else {
/* clicked ones is child checkbox */
var parentId = clicked.dataset.parent;
var checkState = clicked.checked;
Array.prototype.slice.call(allCheckboxes).forEach(function(c) {
/* search checkboxes having data-parent same as clicked ones and is not checked */
if (parentId === c.dataset.parent && !c.checked) {
checkState = false;
return false;
}
});
/* search parent checkbox of clicked ones */
Array.prototype.slice.call(allCheckboxes).forEach(function(c) {
if (c.id === parentId) {
c.checked = checkState;
return false;
}
});
}
};
/* wait till DOM renderes and available to bind event listneres */
document.addEventListener('DOMContentLoaded', function() {
/* fetch all checkboxes having attributes data-parent and id */
allCheckboxes = document.querySelectorAll('input[type=checkbox][data-parent][id]');
/* iterate over all checkboxed to bind click listeners */
Array.prototype.slice.call(allCheckboxes).forEach(function(c) {
c.addEventListener('click', toggleCheck);
});
});
div {
margin-left: 1.5rem;
}
<div>
<label><input type="checkbox" data-parent="-1" id="c1"/>Check Box 1</label>
<div>
<label><input type="checkbox" data-parent="c1" id="c2">Check Box 2</label>
<label><input type="checkbox" data-parent="c1" id="c3">Check Box 3</label>
</div>
</div>
<div>
<label><input type="checkbox" data-parent="-1" id="c4">Check Box 1</label>
<div>
<label><input type="checkbox" data-parent="c4" id="c5">Check Box 2</label>
<label><input type="checkbox" data-parent="c4" id="c6">Check Box 3</label>
</div>
</div>
P.S. </input> is invalid tag.
Edited: Regarding checkState since as of now I have not provided any intermediate state for parent checkbox, so what I did is took the checked state of clicked child checkbox, if its checked then searched from the list of other remaining child checkboxes having same parent id. When encountered anymore child checkboxes which is not checked then I simply mark parent checkbox as unchecked.
With intermediate: Well, its not that fancy but does the trick.
let allCheckboxes;
let repeat = Array.prototype.slice;
let applyState = function(checkbox, state) {
let classes = checkbox.parentNode.classList;
if (!state || !checkbox.checked) {
classes.remove("checked");
classes.remove("intermediate");
checkbox.dataset.state = 0;
}
if (1 === state || checkbox.checked) {
classes.add("checked");
checkbox.dataset.state = 1;
}
if (2 === state) {
classes.remove("checked");
classes.add("intermediate");
checkbox.dataset.state = 2;
}
}
/* checkbox click handler */
let toggleCheck = function(e) {
e.stopPropagation();
var clicked = this;
applyState(clicked);
/* clicked ones is the parent */
if ('-1' === clicked.dataset.parent) {
/* search child checkboxes having data-parent=id of clicked ones */
repeat.call(allCheckboxes).forEach(function(c) {
if (c.dataset.parent === clicked.id) {
/* set checked state same as clicked ones */
c.checked = clicked.checked;
applyState(c);
}
});
} else {
/* clicked ones is child checkbox */
var parentId = clicked.dataset.parent;
var check = 0,
uncheck = 0;
repeat.call(allCheckboxes).forEach(function(c) {
/* search checkboxes having data-parent same as clicked ones */
if (parentId === c.dataset.parent) {
if (c.checked) {
check++;
} else {
uncheck++;
}
}
});
/* search parent checkbox of clicked ones */
repeat.call(allCheckboxes).forEach(function(c) {
if (c.id === parentId) {
var state = 1;
if (0 === check) {
state = 0;
c.checked = false;
} else if (0 < uncheck) {
state = 2;
}
applyState(c, state);
return false;
}
});
}
};
/* wait till DOM renderes and available to bind event listneres */
document.addEventListener('DOMContentLoaded', function() {
/* fetch all checkboxes having attributes data-parent and id */
allCheckboxes = document.querySelectorAll('input[type=checkbox][data-parent][id]');
/* iterate over all checkboxed to bind click listeners */
repeat.call(allCheckboxes).forEach(function(c) {
c.addEventListener('click', toggleCheck);
});
});
div {
margin-left: 1.5rem;
}
label>input {
display: none;
}
label:before {
cursor: pointer;
content: "";
padding: 7px;
border: 1px solid #000;
background-color: #fff;
display: inline-block;
margin-left: 2px;
margin-right: 2px;
vertical-align: top;
}
label.checked:before,
label.intermediate:before {
color: blue;
border-color: blue;
}
label.checked:before {
content: "\2713";
padding: 0px 3px;
font-size: 10px;
}
label.intermediate:before {
content: "\2012";
padding: 0px 4px;
font-size: 11px;
}
<div>
<label><input type="checkbox" data-parent="-1" id="c1"/>Check Box 1</label>
<div>
<label><input type="checkbox" data-parent="c1" id="c2">Check Box 2</label>
<label><input type="checkbox" data-parent="c1" id="c3">Check Box 3</label>
</div>
</div>
<div>
<label><input type="checkbox" data-parent="-1" id="c4">Check Box 1</label>
<div>
<label><input type="checkbox" data-parent="c4" id="c5">Check Box 2</label>
<label><input type="checkbox" data-parent="c4" id="c6">Check Box 3</label>
</div>
</div>

Here's what I would do. One thing to note, this solution does not support IE11 or below, as it uses closest() to find parent nodes by a selector.
https://caniuse.com/#search=closest
(You may have to click the GIF to get it to play.)
<div data-checkbox-group>
<label><input type="checkbox" data-master-checkbox /> Master</label>
<div>
<label><input type="checkbox" /> Check Box 1</label><br>
<label><input type="checkbox" /> Check Box 2</label><br>
<label><input type="checkbox" /> Check Box 3</label><br>
<label><input type="checkbox" /> Check Box 4</label><br>
<label><input type="checkbox" /> Check Box 5</label><br>
</div>
</div>
<hr>
<div data-checkbox-group>
<label><input type="checkbox" data-master-checkbox /> Master</label>
<div>
<label><input type="checkbox" /> Check Box 1</label><br>
<label><input type="checkbox" /> Check Box 2</label><br>
<label><input type="checkbox" /> Check Box 3</label><br>
<label><input type="checkbox" /> Check Box 4</label><br>
<label><input type="checkbox" /> Check Box 5</label><br>
</div>
</div>
<hr>
<div data-checkbox-group>
<label><input type="checkbox" data-master-checkbox /> Master</label>
<div>
<label><input type="checkbox" /> Check Box 1</label><br>
<label><input type="checkbox" /> Check Box 2</label><br>
<label><input type="checkbox" /> Check Box 3</label><br>
<label><input type="checkbox" /> Check Box 4</label><br>
<label><input type="checkbox" /> Check Box 5</label><br>
</div>
</div>
<hr>
<script>
var toggleChecks = function() {
var isMaster = this.hasAttribute('data-master-checkbox')
var group = this.closest('[data-checkbox-group]')
var boxes = group.querySelectorAll('input[type=checkbox]:not([data-master-checkbox])')
var master = isMaster ? this : group.querySelector('input[type=checkbox][data-master-checkbox]')
if (isMaster) {
// Set all children to the value of the parent
for(var i = 0; i < boxes.length; i++) {
boxes[i].checked = this.checked
}
} else {
// Toggle all children to the state of the master
var checkedCount = 0
for(var i = 0; i < boxes.length; i++) {
if(boxes[i].checked) { checkedCount += 1 }
}
master.checked = checkedCount == boxes.length
master.indeterminate = !master.checked && !checkedCount == 0
}
}
var nodes = document.querySelectorAll('[data-checkbox-group] input[type=checkbox]')
for(var i = 0; i < nodes.length; i++) {
nodes[i].addEventListener('change', toggleChecks)
}
</script>

Related

Remove unchecked item from text display & push selected checkboxes into a button element

I've managed to get a text to display when its checked. Whenever its unchecked the text still seems to stay, anyway to remove it? Also, is there anyway to push selected checked boxes into a button element.
const check = document.querySelectorAll('.accordion-content li');
const checkBox = Array.from(check);
const filtersDisplay = document.querySelector('.search-menu .filter-box');
checkBox.forEach(function(list) {
list.addEventListener('change', function() {
console.log(list.textContent);
filtersDisplay.textContent = list.textContent;
})
})
<div class="search-menu">
<h2>Search Menu</h2>
<input class="search-bar"type="search" placeholder="Search..">
<button class="search-bar-button">Go</button>
<br>
<button class="filter-box">Selected filters will display here</button>
</div>
<!-- Catagories List -->
<br>
<button class="accordion">Catagories</button>
<div class="accordion-content">
<li>
<label>
<input type="checkbox" name="checkbox" />Item 1
</label>
</li>
<li>
<label>
<input type="checkbox" name="checkbox" />Item 2
</label>
</li>
<li>
<label>
<input type="checkbox" name="checkbox" />Item 3
</label>
</li>
</div>
You can display the selected value and remove it using Set
const check = document.querySelectorAll('.accordion-content li');
const checkBox = Array.from(check);
const filtersDisplay = document.querySelector('.search-menu .filter-box');
const defaultText = "Selected filters will display here";
const selected = new Set();
function showValues(set) {
if (set.size === 0) filtersDisplay.textContent = defaultText;
else {
filtersDisplay.innerHTML = "";
const fragment = document.createDocumentFragment();
for (let el of set) {
const btn = document.createElement("button");
btn.textContent = (el);
fragment.appendChild(btn);
}
filtersDisplay.appendChild(fragment);
}
}
checkBox.forEach(function(list) {
list.addEventListener('change', function(el) {
const text = list.textContent.trim();
if (selected.has(text)) {
selected.delete(text)
} else selected.add(text)
showValues(selected);
})
})
.filter-box {
background-color: #f5f5f5;
display: flex;
gap: .5rem;
margin-top: 1rem;
padding: .5rem 1rem;
border-radius: 4px;
}
.filter-box button{
background-color: black;
color: white;
border-radius: 24px;
border: none;
}
<div class="search-menu">
<h2>Search Menu</h2>
<input class="search-bar" type="search" placeholder="Search..">
<button class="search-bar-button">Go</button>
<br />
<div class="filter-box">Selected filters will display here</div>
</div>
<!-- Categories List -->
<br />
<button class="accordion">Categories</button>
<div class="accordion-content">
<li>
<label>
<input type="checkbox" name="checkbox" />Item 1
</label>
</li>
<li>
<label>
<input type="checkbox" name="checkbox" />Item 2
</label>
</li>
<li>
<label>
<input type="checkbox" name="checkbox" />Item 3
</label>
</li>
</div>
Pass the event argument to the listener function of change event. The target.checked property will return true/false based on checkbox state.
checkBox.forEach(function(list) {
list.addEventListener('change', function(e) {
filtersDisplay.textContent = e.target.checked ? list.textContent : 'Selected filters will display here';
})
})
``
Create an array and maintain the list of checked checkbox. On checking or unchecking remove the element from the array. Then iterate through the array and display buttons
const check = document.querySelectorAll('.accordion-content li');
const checkBox = Array.from(check);
const filtersDisplay = document.querySelector('.search-menu .filter-box');
let checkedBox = [];
const txt = 'Selected filters will display here'
checkBox.forEach(function(list) {
list.addEventListener('change', function(e) {
if (!checkedBox.includes(list.textContent.trim())) {
checkedBox.push(list.textContent.trim());
} else {
checkedBox = checkedBox.filter(item => item !== list.textContent.trim())
}
createButton()
})
})
function createButton() {
document.getElementById('filter-box').innerHTML = '';
if (checkedBox.length !== 0) {
document.getElementById('filter-box').innerHTML = checkedBox.map(item => `<button>${item}</button>`).join('')
} else {
document.getElementById('filter-box').innerHTML = txt
}
}
<div class="search-menu">
<h2>Search Menu</h2>
<input class="search-bar" type="search" placeholder="Search..">
<button class="search-bar-button">Go</button>
<br>
<div class="filter-box" id="filter-box">Selected filters will display here
</div>
</div>
<!-- Catagories List -->
<br>
<button class="accordion">Catagories</button>
<div class="accordion-content">
<li>
<label><input type="checkbox" name="checkbox" />Item 1</label>
</li>
<li>
<label>
<input type="checkbox" name="checkbox" />Item 2
</label>
</li>
<li>
<label>
<input type="checkbox" name="checkbox" />Item 3
</label>
</li>
</div>

Condition: input:checked with the same class

I would like to have a little help on an enigma that I have.
I have a button that changes according to the number of input:checked
but I would like to add a condition which is: select of the checkboxes of the same class.
for example can I have 2 or more input.
<input class="banana" type="checkbox" value="Cavendish">
<input class="banana" type="checkbox" value="Goldfinger">
<input class="chocolato" type="checkbox" value="cocoa powder">
<input class="chocolato" type="checkbox" value="milk chocolate">
<input class="apple" type="checkbox" value="honneycrisp">
<input class="apple" type="checkbox" value="granny smith">
I can't use attribute name or value. it is not possible to modify the inputs.
the condition:
$('input[type="checkbox"]').click(function(){
if($('input[type="checkbox"]:checked').length >=2){
////////
if (my classes are the same) {
$('#btn').html("click me").prop('disabled', false);
} else {
$('#btn').html("too bad").prop('disabled', true);
}
//////
}
I try with
var checkClass = [];
$.each($("input[type="checkbox"]:checked"), function() {
checkClass.push($(this).attr('class'));
});
I don't know if I'm going the right way or if I'm complicating the code but a little help would be welcome. For the moment my attempts have been unsuccessful.
The following function will reference the first checkbox that's checked className and enable each checkbox that has said className whilst disabling all other checkboxes. Details are commented in Snippet.
// All checkboxes
const all = $(':checkbox');
// Any change event on any checkbox run function `matchCategory`
all.on('change', matchCategory);
function matchCategory() {
// All checked checkboxes
const checked = $(':checkbox:checked');
let category;
// if there is at least one checkbox checked...
if (checked.length > 0) {
// ...enable (.btn)...
$('.btn').removeClass('off');
// ...get the class of the first checked checkbox...
category = checked[0].className;
// ...disable ALL checkboxes...
all.attr('disabled', true);
// ...go through each checkbox...
all.each(function() {
// if THIS checkbox has the class defined as (category)...
if ($(this).is('.' + category)) {
// ...enable it
$(this).attr('disabled', false);
// Otherwise...
} else {
// ...disable and uncheck it
$(this).attr('disabled', true).prop('checked', false);
}
});
// Otherwise...
} else {
// ...enable ALL checkboxes...
all.attr('disabled', false);
// ...disable (.btn)
$('.btn').addClass('off');
}
return false;
}
.off {
pointer-events: none;
opacity: 0.4;
}
<input class="beverage" type="checkbox" value="Alcohol">
<label>🍸</label><br>
<input class="beverage" type="checkbox" value="Coffee">
<label>☕</label><br>
<input class="dessert" type="checkbox" value="cake">
<label>🍰</label><br>
<input class="dessert" type="checkbox" value="Ice Cream">
<label>🍨</label><br>
<input class="appetizer" type="checkbox" value="Salad">
<label>🥗</label><br>
<input class="appetizer" type="checkbox" value="Bread">
<label>🥖</label><br>
<button class='btn off' type='button '>Order</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
some thing like that ?
const
bt_restart = document.getElementById('bt-restart')
, chkbx_all = document.querySelectorAll('input[type=checkbox]')
;
var checked_class = ''
;
bt_restart.onclick = _ =>
{
checked_class = ''
chkbx_all.forEach(cbx=>
{
cbx.checked=cbx.disabled=false
cbx.closest('label').style = ''
})
}
chkbx_all.forEach(cbx=>
{
cbx.onclick = e =>
{
if (checked_class === '') checked_class = cbx.className
else if (checked_class != cbx.className )
{
cbx.checked = false
cbx.disabled = true
cbx.closest('label').style = 'color: grey'
}
}
})
<button id="bt-restart">restart</button> <br> <br>
<label> <input class="banana" type="checkbox" value="Cavendish" > a-Cavendish </label> <br>
<label> <input class="banana" type="checkbox" value="Goldfinger" > a-Goldfinger </label> <br>
<label> <input class="chocolato" type="checkbox" value="cocoa powder" > b-cocoa powder </label> <br>
<label> <input class="chocolato" type="checkbox" value="milk chocolate"> b-milk chocolate </label> <br>
<label> <input class="apple" type="checkbox" value="honneycrisp" > c-honneycrisp </label> <br>
<label> <input class="apple" type="checkbox" value="granny smith" > c-granny smith </label> <br>
In fact it's like a Matching Pairs card game
this answer is without global checked_group variable, and respecting epascarello message about data attribute see also usage.
Adding a repentance on uncheck elements
const
bt_restart = document.getElementById('bt-restart')
, chkbx_all = document.querySelectorAll('input[type=checkbox]')
;
function clearGame()
{
chkbx_all.forEach(cbx=>
{
cbx.checked = cbx.disabled = false
cbx.closest('label').style = ''
})
}
bt_restart.onclick = clearGame
chkbx_all.forEach(cbx=>
{
cbx.onclick = e =>
{
let checkedList = document.querySelectorAll('input[type=checkbox]:checked')
if (cbx.checked)
{
let checked_group = ''
checkedList.forEach(cEl=>{ if (cEl !== cbx) checked_group = cEl.dataset.group })
if (checked_group === '') checked_group = cbx.dataset.group
else if (checked_group !== cbx.dataset.group )
{
cbx.checked = false // you need to uncheck wrong group checkboxes for preserving checkedList
cbx.disabled = true
cbx.closest('label').style = 'color: grey'
}
}
else if (checkedList.length === 0) // case of cheked repentir
clearGame()
}
})
<button id="bt-restart">restart</button> <br> <br>
<label> <input data-group="banana" type="checkbox" value="Cavendish" > a-Cavendish </label> <br>
<label> <input data-group="banana" type="checkbox" value="Goldfinger" > a-Goldfinger </label> <br>
<label> <input data-group="chocolato" type="checkbox" value="cocoa powder" > b-cocoa powder </label> <br>
<label> <input data-group="chocolato" type="checkbox" value="milk chocolate"> b-milk chocolate </label> <br>
<label> <input data-group="apple" type="checkbox" value="honneycrisp" > c-honneycrisp </label> <br>
<label> <input data-group="apple" type="checkbox" value="granny smith" > c-granny smith </label> <br>

How to append an array to an input, wrapping each value in a span?

I've got some checkboxes, and each time I check/uncheck them I'd like their values to be appended to a search box, with each value being wrapped in a span.
Here's what I've got so far:
right now I'm just adding the array to the value of the input each time the array changes:
updateInputBox = function(query) {
var inputBox;
inputBox = $("#searchBox")
inputBox.val(checkboxes);
}
See here: https://jsfiddle.net/g7n9zpow/
I'm having trouble thinking of how to get the <span> around each value. I thought of iterating the array, and appending the values to the value of the input, but then I'd have to check first if the input is already blank.. and it gets messy. I thought this would be easy.
EDIT
turns out trying to put a <span/> into an input is dumb. I wanted it so that I could style each value like this:
You can use a div element with contenteditable attribute set , button elements ; use $.map() , $.filter() ; css :before to style "x"
var checkboxes = [],
elems = $(":checkbox"),
inputBox = $("#searchBox");
updateInputBox = function(query) {
inputBox.html(query);
}
elems.change(function() {
checkboxes = $.map(elems.filter(":checked"), function(el, i) {
return checkboxes.indexOf(el.value) < 0
&& "<button>" + el.value + "</button>"
});
updateInputBox(checkboxes)
console.log(checkboxes);
});
#searchBox {
border: 1px solid gray;
width: 80%;
}
button:before {
content: "x ";
color: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="checkboxes">
<label>
<input type="checkbox" value="Tom Hanks" name="actorName">Tom Hanks</label>
<label>
<input type="checkbox" value="Tim Allen" name="actorName">Tim Allen</label>
<label>
<input type="checkbox" value="Don Rickles" name="actorName">Don Rickles</label>
<label>
<input type="checkbox" value="Jim Varney" name="actorName">Jim Varney</label>
<label>
<input type="checkbox" value="Wallace Shawn" name="actorName">Wallace Shawn</label>
<label>
<input type="checkbox" value="Fantasy" name="genreName">Fantasy</label>
<label>
<input type="checkbox" value="Comedy" name="genreName">Comedy</label>
<label>
<input type="checkbox" value="Children" name="genreName">Children</label>
<label>
<input type="checkbox" value="Animation" name="genreName">Animation</label>
<label>
<input type="checkbox" value="Adventure" name="genreName">Adventure</label>
<label>
<input type="checkbox" value="USA" name="countryName">USA</label>
</div>
<div contenteditable id="searchBox"></div>
jsfiddle https://jsfiddle.net/g7n9zpow/11/
You can do it like following using map() function.
$(':checkbox').change(function () {
var checkboxes = $(':checkbox:checked').map(function () {
return '<span>' + this.value + '</span>'
}).get().join('');
$("#searchBox").val(checkboxes);
})
UPDATED FIDDLE
Just wrap them in a <span></span> then push:
$(':checkbox').change(function() {
var $this = $(this);
if ($(this).is(':checked')) {
checkboxes.push('<span>'+$this.val()+'</span>') // <-- here
updateInputBox(checkboxes)
} else {
index = checkboxes.indexOf('<span>'+$this.val()+'</span>'); // <-- and here
if (index > -1)
checkboxes.splice(index, 1);
updateInputBox(checkboxes)
}
return console.log(checkboxes);
});
Updated fiddle

Checkbox bind/unbind logic

Hi i have a situation where the binding for a table containing checkbox is done at the header checkbox
i.e when u select the header check all table rows get selected .
but due to this the problem comes when i unselect an row from the table the header chekcbox should get unselected which is not happening
and suppose i uncheck the header checkbox entire table row will be unchecked coz of the binding issue
please suggest some logic to solve it
I tried retrieving the table row checkbox value and again rendering it but it's a memory constraint.
Thanks in advance
HTML
<input type="checkbox" id="header" />
<li>
<input type="checkbox" class="sub" />
</li>
<li>
<input type="checkbox" class="sub" />
</li>
<li>
<input type="checkbox" class="sub" />
</li>
JS
var headCheckbox = document.getElementById('header');
var subCheckbox = document.getElementsByClassName('sub');
headCheckbox.addEventListener('change', function (e) {
for (var i = 0; i < subCheckbox.length; i++) {
subCheckbox[i].checked = (this.checked ? true : false);
}
});
for (var i = 0; i < subCheckbox.length; i++) {
subCheckbox[i].addEventListener('change', function (e) {
if (!this.checked) {
headCheckbox.checked = false;
} else {
var checked = 0;
for (var i = 0; i < subCheckbox.length; i++) {
if (subCheckbox[i].checked) checked++;
}
if (checked == subCheckbox.length) headCheckbox.checked = true;
}
});
}
DEMO
You may do like below to
1. Select all checkbox on selecting header checkbox.
2. UnSelect header checkbox on unselecting any child checkbox.
3. Select header checkbox on selecting all child checkbox.
JavaScript :
function selectAll(source)
{
var checkboxes = document.getElementsByName('foo');
for(var i=0, n=checkboxes.length;i<n;i++) {
checkboxes[i].checked = source.checked;
}
}
function selectChk(src)
{
var isAllChecked = true;
var headerChk = document.getElementsByName('headerChk');
if(!src.checked){
headerChk[0].checked = false;
}
else{
var checkboxes = document.getElementsByName('foo');
for(var i=0, n=checkboxes.length;i<n;i++) {
if(!checkboxes[i].checked)
isAllChecked = false;
}
if(isAllChecked)
headerChk[0].checked = true;
}
}
HTML :
<input type="checkbox" onClick="selectAll(this)" name="headerChk" /> Select All<br/>
<input type="checkbox" name="foo" value="bar1" onClick="selectChk(this)"> Bar 1<br/>
<input type="checkbox" name="foo" value="bar2" onClick="selectChk(this)"> Bar 2<br/>
<input type="checkbox" name="foo" value="bar3" onClick="selectChk(this)"> Bar 3<br/>
<input type="checkbox" name="foo" value="bar4" onClick="selectChk(this)"> Bar 4<br/>

How can I only select one radio button?

I am creating a review-control and using radiobutton for grade selection. I wrote some simple js to add a diffrent class when a radiobutton is checked.
The problem is that you can check every radio button, I want the user only to check one value. I writing this in javascript, but jQuery is welcome or a smartare solution.
Demo : http://jsfiddle.net/cbqt8/5/
HTML:
<div class="reviews">
<label class="input-check">
<input onchange="change_state(this)" type="radio" value="1" name="review[rating]" /> Bad
</label>
<label class="input-check">
<input onchange="change_state(this)" type="radio" value="2" name="review[rating]" /> Its okey
</label>
<label class="input-check">
<input onchange="change_state(this)" type="radio" value="3" name="review[rating]" /> Great
</label>
<label class="input-check">
<input onchange="change_state(this)" type="radio" value="4" name="review[rating]" /> Awesome
</label>
<label class="input-check">
<input onchange="change_state(this)" type="radio" value="5" name="review[rating]" />Super
</label>
</div>
JavaScript:
function change_state(obj) {
if (obj.checked) {
//if radiobutton is being checked, add a "checked" class
obj.parentNode.classList.add("checked");
}
else {
//else remove it
obj.parentNode.classList.remove("checked");
}
}
CSS:
/*reviews box*/
.reviews{
padding: 25px;
margin:0;
}
/*this is the style of an radio "button"*/
.input-check {
display: inline-block;
height:20px;
padding:5px 8px;
background:green;
width:90px;
color:white;
text-align: center;
}
/* This is the style for a radio "button" */
.input-check.checked{
background:red;
color:black;
font-weight:bold;
}
/*Hide the radiobutton*/
.input-check input {
display:none;
}
You got to remove the checked class for previously checked item.
jsFiddle: http://jsfiddle.net/P8jB8/
function change_state(obj) {
if (obj.checked) {
var checkedNodes = getElementsByClassName(document, "checked");
for (var i=0;i<checkedNodes.length;i++) {
checkedNodes[i].classList.remove("checked");
}
//if radiobutton is being checked, add a "checked" class
obj.parentNode.classList.add("checked");
}
else {
//else remove it
obj.parentNode.classList.remove("checked");
}
}
function getElementsByClassName(node,classname) {
if (node.getElementsByClassName) { // use native implementation if available
return node.getElementsByClassName(classname);
} else {
return (function getElementsByClass(searchClass,node) {
if ( node == null )
node = document;
var classElements = [],
els = node.getElementsByTagName("*"),
elsLen = els.length,
pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"), i, j;
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
})(classname, node);
}
}
​

Categories