javascript check all and uncheck all checkbox - javascript

I have select all check box with some option when i click select all i select all the option and when i remove the select all i remove it from all option and the code below work for that.
What i try to do is when i unselect one of the option the select all box should be unselected and if i select all the option without selecting the select all option the check all box should be selected.
How can i do that?
let checkboxes = document.querySelectorAll("input[type = 'checkbox']");
function checkAll(myCheckBox) {
if (myCheckBox.checked == true) {
checkboxes.forEach(function(checkbox) {
checkbox.checked = true;
});
} else {
checkboxes.forEach(function(checkbox) {
checkbox.checked = false;
});
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-content: center;
}
input[type="checkbox"] {
margin-bottom: 10px;
cursor: pointer;
}
input[type="checkbox"]:not(:first-child) {
margin-left: 20px;
}
<div class="container">
<input type="checkbox" id="check-all" onchange="checkAll(this)">
<label for="check-all">Select All</label>
<br/>
<input type="checkbox" id="option-a">
<label for="option-a">Option A</label>
<br/>
<input type="checkbox" id="option-b">
<label for="option-b">Option B</label>
<br/>
<input type="checkbox" id="option-c">
<label for="option-c">Option C</label>
<br/>
</div>

You can add a change event listener to all of those checkboxes (except for the automatic select all checkbox).
So in this demo I used a disciminant being the class auto that only the "select all" checkbox has.
Then I select all elements being input but not having the class auto.
And for each of those I add an event listener for the change event that will uncheck the "select all" checkbox if any of those was unchecked and that will check the "select all" checkbox if otherwise all of them are checked.
let checkboxes = document.querySelectorAll("input[type='checkbox']");
let cbActual = document.querySelectorAll('input[type=checkbox]:not([class=auto])');
cbActual.forEach(
cb => {
cb.addEventListener('change', (event)=>{
if(!event.target.checked)
document.getElementById('check-all')
.checked = false;
else{
if( [...cbActual].every(cb => cb.checked === true) )
document.getElementById('check-all')
.checked = true;
}
});
}
);
function checkAll(myCheckBox) {
if (myCheckBox.checked == true) {
checkboxes.forEach(function(checkbox) {
checkbox.checked = true;
});
} else {
checkboxes.forEach(function(checkbox) {
checkbox.checked = false;
});
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-content: center;
}
input[type="checkbox"] {
margin-bottom: 10px;
cursor: pointer;
}
input[type="checkbox"]:not(:first-child) {
margin-left: 20px;
}
<div class="container">
<input type="checkbox" id="check-all" onchange="checkAll(this)" class="auto">
<label for="check-all">Select All</label>
<br/>
<input type="checkbox" id="option-a">
<label for="option-a">Option A</label>
<br/>
<input type="checkbox" id="option-b">
<label for="option-b">Option B</label>
<br/>
<input type="checkbox" id="option-c">
<label for="option-c">Option C</label>
<br/>
</div>

When checkall is clicked either all or none are selected. When one of the options are checked/unchecked the status of checkall is decided based on the filter function.
I changed the markup of the form a bit. You can "group" check boxes on their name. And try avoiding IDs in a form -- in general it is better to use the name attribute.
document.addEventListener('DOMContentLoaded', e => {
document.forms.form01.addEventListener('change', result_change);
});
function result_change(e) {
let form = e.target.form;
/* e.target.form.option could either be a NodeList or just one Element.
A iterable is needed. */
let options = (form.option.length) ? form.option : [form.option];
switch (e.target.name) {
case 'checkall':
let checked = e.target.checked;
[...options].forEach(option => option.checked = checked);
break;
case 'option':
let allchecked = ([...options].filter(option => !option.checked).length == 0) ? ? true;
form.checkall.checked = allchecked ? true : false;
break;
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-content: center;
}
input[type="checkbox"] {
margin-bottom: 10px;
cursor: pointer;
}
input[type="checkbox"]:not(:first-child) {
margin-left: 20px;
}
<form name="form01">
<input type="checkbox" name="checkall">
<label for="check-all">Select All</label>
<br/>
<input type="checkbox" name="option" value="a">
<label for="option-a">Option A</label>
<br/>
<input type="checkbox" name="option" value="b">
<label for="option-b">Option B</label>
<br/>
<input type="checkbox" name="option" value="c">
<label for="option-c">Option C</label>
<br/>
</form>

Prefer to use event propagation to handle the change events of all checkboxes in one listener.
To make use of event propagation, you have to be able to distinguish them from the "Select all" checkbox. To distinuish them, you can:
Use a class (on either the "Select all" or all other checkboxes).
Group the checkboxes (except the "Select all" checkbox) in an element.
Check if the changing checkbox is the first (i.e. the "Select all") checkbox.
...
I chose to use a grouping element so that the "Select all" checkbox is not included:
const cbAll = document.getElementById("cb-all");
const cbGroup = document.getElementById("cb-group");
// NodeList has .forEach() but not .every(). Transform to an array, which has both.
const checkboxes = Array.from(cbGroup.querySelectorAll("input[type=checkbox]"));
cbAll.addEventListener("change", () => {
// If cbAll.checked changes, cbAll.checked should override all other checkboxes' checked.
checkboxes.forEach(cb => cb.checked = cbAll.checked);
});
// This listener will be called if *any* checkbox (in cbGroup) changes.
// Update cbAll.checked to true if all checkboxes are checked; otherwise false.
cbGroup.addEventListener("change", () => {
const areAllChecked = checkboxes.every(cb => cb.checked);
cbAll.checked = areAllChecked;
});
label {display: block}
#cb-group {margin-inline-start: 1.2rem}
<label for="cb-all"><input id="cb-all" type="checkbox"> Select all</label>
<div id="cb-group">
<label for="cb-1"><input id="cb-1" type="checkbox"> First option</label>
<label for="cb-2"><input id="cb-2" type="checkbox"> Second option</label>
<label for="cb-3"><input id="cb-3" type="checkbox"> Third option</label>
</div>
Alternatively you can add listeners to all checkboxes individually.
Checkboxes can also be in a "third" state: Indeterminate. Note: This is not a true state, as checkboxes can only be either checked or unchecked. An indeterminate checkbox hides its checkedness under the pretence of being indeterminate.
This is most commonly used for checkboxes like this "Select all" checkbox; where a checkbox describes the state of a group of checkboxes.
The above example can be modified to make use of it:
const cbAll = document.getElementById("cb-all");
const cbGroup = document.getElementById("cb-group");
const checkboxes = Array.from(cbGroup.querySelectorAll("input[type=checkbox]"));
cbAll.addEventListener("change", () => {
checkboxes.forEach(cb => cb.checked = cbAll.checked);
});
cbGroup.addEventListener("change", () => {
const amountChecked = checkboxes.reduce((amount, cb) => {
// Number(bool) returns 1 if bool === true; otherwise 0.
return amount + Number(cb.checked);
}, 0);
const areAllChecked = amountChecked === checkboxes.length;
const areSomeChecked = amountChecked > 0;
cbAll.checked = areAllChecked;
cbAll.indeterminate = areSomeChecked && !areAllChecked;
});
label {display: block}
#cb-group {margin-inline-start: 1.2rem}
<label for="cb-all"><input id="cb-all" type="checkbox"> Select all</label>
<div id="cb-group">
<label for="cb-1"><input id="cb-1" type="checkbox"> First option</label>
<label for="cb-2"><input id="cb-2" type="checkbox"> Second option</label>
<label for="cb-3"><input id="cb-3" type="checkbox"> Third option</label>
</div>

Related

How do I dynamically get the value of an element from an array of elements?

I have a form with 3 checkboxes. I'm trying to the value of whichever checkbox is clicked on. I'm able to get the value of a hardcoded checkbox index (checkbox[0] for example), but I can't get the value of checkbox[i] with vanilla JS.
document.addEventListener("DOMContentLoaded", function() {
var checkboxes = document.getElementsByClassName('checkbox');
var listType = document.getElementById('ListType');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('click', function() {
var inputByIndex = checkboxes[0].value; //I can get the value of the first element, but I can't get the value of whichever checkbox is checked. checkbox[i] doesn't work.
listType.classList.add(inputByIndex);
var spanType = document.getElementById("type");
spanType.innerText = inputByIndex;
});
}
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
Fiddle
You can use event.currentTarget to access the element on which event has occurred.
The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM.
document.addEventListener("DOMContentLoaded", function() {
var checkboxes = document.getElementsByClassName('checkbox');
var listType = document.getElementById('ListType');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('click', function(event) {
var inputByIndex = event.currentTarget.value;
listType.classList.add(inputByIndex);
var spanType = document.getElementById("type");
spanType.innerText = inputByIndex;
});
}
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
In the for loop, use let instead of var to make it work:
document.addEventListener("DOMContentLoaded", function() {
var checkboxes = document.getElementsByClassName('checkbox');
var listType = document.getElementById('ListType');
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('click', function() {
var inputByIndex = checkboxes[i].value; //I can get the value of the first element, but I can't get the value of whichever checkbox is checked. checkbox[i] doesn't work.
listType.classList.add(inputByIndex);
var spanType = document.getElementById("type");
spanType.innerText = inputByIndex;
});
}
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
the checkboxes list doesn't exist within the closure of the onclick funcion. Instead use this.value.
JS fiddle
Delegate
You need to think of the CSS for more than one listType color or use a set of radio buttons
document.addEventListener("DOMContentLoaded", function() {
document.getElementById('ListTypes').addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.type && tgt.type === 'checkbox') {
const values = [...tgt.form.querySelectorAll("[type=checkbox]:checked")].map(chk => chk.value);
document.getElementById("type").textContent = values.join(", ")
document.getElementById("ListType").classList.add(...values);
}
});
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
You just need to select them all using the method you would like (I used querySelectorAll & ) and do an iteration over them (I used forEach()).
This is the most simple function you can ever find.
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach(singleCheckbox => {
singleCheckbox.addEventListener('click', () => alert(singleCheckbox.id))
});
<label for="first">First<input type="checkbox" id="first"/></label>
<label for="second">Second<input type="checkbox" id="second"/></label>
<label for="third">Third<input type="checkbox" id="third"/></label>
Just to make clear what was actually the problem with your code...
At the time you click handler will be fired the for loop will end its work and thus, the value of i will become exactly checkboxes.length, and of course, there is no checkbox with such an index, because the last of them has index (checkboxes.length - 1). So the reason is that the code inside of the handler is executed after for loop ends its work.
The solutions were already provided by other users.

Can you onblur a set of checkboxes?

I have a set of checkboxes, and validation such that at least one of those checkboxes need to be checked on submit. But I want to be able to set a validation error if the user blurs out of the set of checkboxes. The problem is that if I do a blur for the last one it doesn't work because they could be shift-tabbing to the second from last checkbox. I've tried to but the onblur in the fieldset tag, but that didn't trigger a blur at all. Is this just a limitation that can't be overcome with plain html and vanilla JS?
You can look at what the next element that is focused is and determine if they are under the same grouping.
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function (event) {
const nextElem = event.relatedTarget;
const fieldSet = elem.closest('fieldset');
const isValid = fieldSet.querySelector("input:checked") !== null;
if (nextElem?.closest('fieldset') !== fieldSet) {
fieldSet.classList.toggle("error", !isValid);
} else if (isValid) {
fieldSet.classList.remove("error");
}
});
});
.error {
color: red;
}
<form>
<fieldset>
<legend>Pizza One</legend>
<input type="checkbox" name="x1-1" id="x1-1">
<label for="x1-1">Cheese</label>
<input type="checkbox" name="x1-2" id="x1-2">
<label for="x1-2">Peppers</label>
<input type="checkbox" name="x1-3" id="x1-3">
<label for="x1=3">Mushrooms</label>
</fieldset>
<fieldset>
<legend>Pizza Two</legend>
<input type="checkbox" name="x2-1" id="x2-1">
<label for="x2-1">Cheese</label>
<input type="checkbox" name="x2-2" id="x2-2">
<label for="x2-2">Peppers</label>
<input type="checkbox" name="x2-3" id="x2-3">
<label for="x2-3">Mushrooms</label>
</fieldset>
<input type="submit" />
</form>
Adding in a trick to use HTML5 validation
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function(event) {
const nextElem = event.relatedTarget;
const fieldSet = elem.closest('fieldset');
const isValid = fieldSet.querySelector("input:checked") !== null;
if (nextElem?.closest('fieldset') !== fieldSet) {
fieldSet.classList.toggle("error", !isValid);
}
});
elem.addEventListener("change", function(event) {
const fieldSet = elem.closest('fieldset');
const isValid = fieldSet.querySelector("input:checked") !== null;
if (isValid) {
fieldSet.classList.remove("error");
fieldSet.querySelectorAll("input").forEach((cb) => {
cb.removeAttribute("required");
});
} else {
fieldSet.querySelectorAll("input").forEach((cb) => {
cb.setAttribute("required", "required");
});
}
});
const changeEvt = document.createEvent("HTMLEvents");
changeEvt.initEvent("change", false, true);
elem.dispatchEvent(changeEvt);
});
.error {
color: red;
}
<form>
<fieldset>
<legend>Pizza One</legend>
<input type="checkbox" name="x1-1" id="x1-1">
<label for="x1-1">Cheese</label>
<input type="checkbox" name="x1-2" id="x1-2">
<label for="x1-2">Peppers</label>
<input type="checkbox" name="x1-3" id="x1-3">
<label for="x1=3">Mushrooms</label>
</fieldset>
<fieldset>
<legend>Pizza Two</legend>
<input type="checkbox" name="x2-1" id="x2-1">
<label for="x2-1">Cheese</label>
<input type="checkbox" name="x2-2" id="x2-2">
<label for="x2-2">Peppers</label>
<input type="checkbox" name="x2-3" id="x2-3">
<label for="x2-3">Mushrooms</label>
</fieldset>
<input type="submit" />
</form>
Based on epascarello's suggestion I was able to create a function that provided similar functionality to the one provided. I have an error span that's underneath the checkboxes. I wanted behavior that would immediately remove that if any checkbox was checked, but only add the error span if the user blurred out of the entire set of checkboxes. Note that there is only one fieldset on this page, and the error span has an specific id I could reference. Here's the function that I got working:
document.querySelectorAll('input[type="checkbox"]').forEach((elem) => {
elem.addEventListener("blur", function (event) {
var errorSpan = document.getElementById("checkboxesErrorSpan");
var isValid = document.querySelector("fieldset").querySelectorAll("input:checked").length > 0;
if (isValid) {
if ((errorSpan.style.display == "inline")) {
errorSpan.style.display = "none";
}
}
else {
if (event.relatedTarget.type != "checkbox") {
if ((errorSpan.style.display == "none")) {
errorSpan.style.display = "inline";
}
}
}
});
});

How to write code for counts prices from checked inputs

I started to learn javascript 2 weeks ago. I want to do my first program which counts all prices from checked input.
But i dont have idea how to do this.
I found something on internet and stackoverflow, but i dont know to do this for my inputs.
Could you help me?
My code
// this function counts all the values
function showPrice() {
var priceOne = document.getElementsByName('price1');
var priceTwo = document.getElementsByName('price2');
var priceThree = document.getElementsByName('price3');
}
You can do this by getting a list of elements for all the inputs, check the ones that are checked, get their values, convert them to numbers and sum them.
Beginning with a list of ids, use Array.map() to transform the list into a list of string ids (1 -> test1).
Then apply getElementById() to each id to get the HTML element.
Then from the element extract and convert the value if the input is checked, otherwise map the element to 0.
Use Array.reduce to sum the values.
Using getElementById, find your output span and set its innerHTML to the total.
function showPrice() {
const total = [1,2,3,4,5,6,7,8,9]
.map(id => `test${id}`)
.map(id => document.getElementById(id))
.map(el => el && el.checked ? Number(el.value) : 0)
.reduce((sum, value) => sum + value, 0);
document.getElementById('getPrice').innerHTML = total;
}
.priceInput {
display: block;
border: 1px solid black;
padding: 10px;
width: 300px;
text-align: center;
margin-left: auto;
margin-right: auto;
}
.priceOutput {
display: block;
border: 1px solid black;
padding: 10px;
width: 300px;
text-align: center;
margin-left: auto;
margin-right: auto;
}
<div class="priceInput">
<p>Part 1</p>
<label for="test1">test1</label>
<input type="radio" name="price1" id="test1" value="10">
<label for="test2">test2</label>
<input type="radio" name="price1" id="test2" value="25">
<label for="test3">test3</label>
<input type="radio" name="price1" id="test3" value="12">
</div>
<div class="priceInput">
<p>Part 2</p>
<label for="test4">test4</label>
<input type="radio" name="price2" id="test4" value="5">
<label for="test5">test5</label>
<input type="radio" name="price2" id="test5" value="7">
<label for="test6">test6</label>
<input type="radio" name="price2" id="test6" value="2">
</div>
<div class="priceInput">
<p>Part 3</p>
<label for="test7">test7</label>
<input type="radio" name="price3" id="test7" value="250">
<label for="test8">test8</label>
<input type="radio" name="price3" id="test8" value="720">
<label for="test9">test9</label>
<input type="radio" name="price3" id="test9" value="410">
</div>
<br>
<div class="priceOutput">
<button onclick="showPrice()">Show Price</button>
<p>Your Price is : <span id="getPrice">0<!--Here i want to get price1(value) + price2(value) + price3(value)--></span> $</p>
</div>
By looking at your code, it seems that you want to get the option the user selected out of the radio buttons and not all radio buttons (referring to the getElementsByName). To do so, you can go over the nodeList returned and see if any of the elements have the checked property.
for(let i = 0; i < priceOne.length; i++){
if(priceOne[i].checked) {
//Get value of the price selected with .value
let priceOneValue = priceOne[i].value;
}
}
After doing this for all your input types, you can sum them up.
JO_VA here is my own code. Can you check it? It's easier for my understanding.
I found just 1 problem and it is : when i remove from HTML input tag "checked" and i klikn only for 1 or 2 radio options, it show NaN in paragraph for price.
BTW sorry for my english (i ussually dont use english language)
function showPrice(){
var pricePlace = document.getElementById("getPrice");
getVal1();
getVal2();
getVal3();
var InputNumber = Number(inputVal1) + Number(inputVal2) + Number(inputVal3);
pricePlace.innerHTML = InputNumber;
}
var inputVal1;
function getVal1(){
var a = document.getElementById("test1");
var b = document.getElementById("test2");
var c = document.getElementById("test3");
if (c.checked) {
inputVal1 = c.value;
}
if (b.checked) {
inputVal1 = b.value;
}
if (a.checked) {
inputVal1 = a.value;
}
}
var inputVal2;
function getVal2(){
var a = document.getElementById("test4");
var b = document.getElementById("test5");
var c = document.getElementById("test6");
if (c.checked) {
inputVal2 = c.value;
}
if (b.checked) {
inputVal2 = b.value;
}
if (a.checked) {
inputVal2 = a.value;
}
}
var inputVal3;
function getVal3(){
var a = document.getElementById("test7");
var b = document.getElementById("test8");
var c = document.getElementById("test9");
if (c.checked) {
inputVal3 = c.value;
}
if (b.checked) {
inputVal3 = b.value;
}
if (a.checked) {
inputVal3 = a.value;
}
}
Or you can check it in https://codepen.io/soorta/pen/gqEGyQ

show checked checkbox values on textarea javascript

I am trying to get all the checkbox checked values on the input field provided. I am using javascript to get the values but it only shows one checked value. When I check another checkbox it displays the second one only.
Here is what i did so far:
<html>
<head>
<script type="text/javascript">
function checkbox(val){
document.getElementById("show").value = val;
}
</script>
</head>
<body>
<form>
<input type="checkbox" id="bk" name="vehicle" onClick="checkbox(this.value);" value="Bike">I have a bike<br></br>
<input type="checkbox" id="cr" name="vehicle" onClick="checkbox(this.value);" value="Car">I have a car<br></br>
<input type="text" id="show" name="vehicle"><br>
<input type="submit" value="Showe">
</form>
</body>
</html>
As I said, this one only shows a single checked value, but I want to show all the checked values on the input field specified!
Thanks!
Your code is only sending the currently clicked item to the method. You need to look at all the checkboxes in that method and find the checked ones, put them in an array, then insert the array value into your input. Also worth noting, when you do it this way and build out the array on each click, it also makes it appear as though items are being removed from the input when you uncheck them.
function checkbox(){
var checkboxes = document.getElementsByName('vehicle');
var checkboxesChecked = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i].value);
}
}
document.getElementById("show").value = checkboxesChecked;
}
<form>
<input type="checkbox" id="bk" name="vehicle" onClick="checkbox();" value="Bike">I have a bike<br></br>
<input type="checkbox" id="cr" name="vehicle" onClick="checkbox();" value="Car">I have a car<br></br>
<input type="text" id="show" name="vehicle"><br>
<input type="submit" value="Showe">
</form>
var txt = document.getElementById( 'droptxt' ),
content = document.getElementById( 'content' ),
list = document.querySelectorAll( '.content input[type="checkbox"]' ),
quantity = document.querySelectorAll( '.quantity' );
txt.addEventListener( 'click', function() {
content.classList.toggle( 'show' )
} )
window.onclick = function( e ) {
if ( !e.target.matches( '.list' ) ) {
if ( content.classList.contains( 'show' ) ) content.classList.remove( 'show' )
}
}
list.forEach( function( item, index ) {
item.addEventListener( 'click', function() {
calc()
} )
} )
function calc() {
for ( var i = 0, arr = []; i < list.length; i++ ) {
let spanArray = [];
document.querySelectorAll('span').forEach(element => {
spanArray.push(element.innerHTML);
});
if ( list[ i ].checked ) arr.push( list[ i ].value + " "+ spanArray)
}
txt.value = arr.join(', ')
}
h1 {
color: #0000ff;
}
#droptxt {
padding: 8px;
width: 300px;
cursor: pointer;
box-sizing: border-box
}
.dropdown {
position: relative;
display: inline-block
}
.content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
overflow: auto;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, .2);
z-index: 1
}
.content div {
padding: 10px 15px
}
.content div:hover {
background-color: #ddd
}
.show {
display: block
}
<h1>KIAAT</h1>
<b>Adding/Removing Checkbox Values into TextArea</b>
<br><br>
<input type="text" id="droptxt" class="list" placeholder="Select the values" readonly>
<div id="content" class="content">
<div id="market" class="list">
<label><input type="checkbox" id="market" class="list" value="Bike" /> I have a bike</label>
</div>
<div class="list">
<label><input type="checkbox" id="banana" class="list" value="Car" /> I have a car</label>
</div>
</div>

How do I check to make sure all my input:radio elements have a value?

I'm working on a form, and I've got a code that works for validating radio fields. However I plan on having many, MANY radio fields and I feel that my current method, which names each radio field individually, to be a bit tedious. I feel there must be a way I can simply select all of them to make sure they've all been checked before processing the form.
Here is my jsFiddle
Current jQuery
$("form").on("keyup change", function(){
food = $(":checked[name=food]");
color = $(":checked[name=color]");
if (food.val() == "" || food.val() == undefined ||
color.val() == "" || color.val() == undefined){
//Do stuff
} else {
//Do other stuff
}
});
jQuery I'm trying
$("form").on("keyup change", function(){
radio_req = $(".required:checked[type=radio]");
if ( radio_req == "" || radio_req == undefined ) {
//Do stuff
} else {
//Do other stuff
}
});
With the 2nd one, I'm trying to see if I can just add a class of required to all my radio fields, and then just see if any .required radio buttons are left unselected/undefined. I feel there has to be a way for this to work. Am I on the right track? I feel like I'm just not selecting this right.
I have updated your fiddle, check it !
I hope it will solve your problem.
You can test the snippet under.
This is the part i modified :
var checker = function(){
var checked = $.unique($(".required:checked[type=radio]").map(function(){
return this.name;
}));
var not_checked = $.unique($(".required:not(:checked)[type=radio]").map(function(){
return this.name;
}));
if (checked.length !== not_checked.length){
$("#submit").prop("disabled", true).removeClass("valid").addClass("invalid");
$(".submit").text("* All fields must be completed and contain valid entries before submitting.");
} else {
$("#submit").prop("disabled", false).removeClass("invalid").addClass("valid");
$(".submit").text("");
}
};
$("form").on("keyup change", checker);
checker();
$(document).ready(function(){
// for each Question we have 3 choices:
// so when we answer we have 1 checked and 2 unchecked
// we loop over question
// we fill 2 arrays(checked, unchecked)
// with names of radio
// for each question we will have something like that
// Question 1 : food
// checked = ['food']; notchecked = ['food','food']
// we make them unique ! it becomes
// checked = ['food']; notchecked = ['food'];
// we know now that the First question have been answered
// we loop over all question :
// checked = ['food'] , notchecked = ['food' , 'color' , 'town' , 'country' , 'car']
// we wait for checking !
// let answer Qestion 2
// checked = ['food' , 'color] , notchecked = ['food' , 'color' , 'town' , 'country' , 'car']
// etc etc . . .
// when checked.length === notchecked.length => we have an answer for all question
var checker = function(){
var checked = $.unique(
$(".required:checked[type=radio]").map(function(){
return this.name;
})
);
var not_checked = $.unique(
$(".required:not(:checked)[type=radio]").map(function(){
return this.name;
})
);
if (checked.length !== not_checked.length){
$("#submit").prop("disabled", true).removeClass("valid").addClass("invalid");
$(".submit").text("* All fields must be completed and contain valid entries before submitting.");
} else {
$("#submit").prop("disabled", false).removeClass("invalid").addClass("valid");
$(".submit").text("");
}
};
$("form").on("keyup change", checker);
checker();
});
input {
margin: 7px;
}
.valid {
background-color: green;
border: 3px solid darkgreen;
color: white;
}
.invalid {
background-color: grey;
border: 3px solid darkgrey;
color: black;
}
.error {
color: red;
}
#submit {
display: block;
border-radius: 10px 10px 10px 10px;
width: 130px;
margin: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<br>Which of the following do you like the most?
<br>
<input type="radio" class="required" name="food" value="pizza">Pizza
<input type="radio" class="required" name="food" value="burgers">Burgers
<input type="radio" class="required" name="food" value="Salads">Salads
<br>
<br>Which of the following colors do you like the most?
<br>
<input type="radio" class="required" name="color" value="red">Red
<input type="radio" class="required" name="color" value="blue">Blue
<input type="radio" class="required" name="color" value="yellow">Yellow
<br>
<br>Which of the following town do you like the most?
<br>
<input type="radio" class="required" name="town" value="red">New York
<input type="radio" class="required" name="town" value="blue">Miami
<input type="radio" class="required" name="town" value="yellow">Las Vegas
<br>
<br>Which of the following country do you like the most?
<br>
<input type="radio" class="required" name="country" value="red">USA
<input type="radio" class="required" name="country" value="blue">Canada
<input type="radio" class="required" name="country" value="yellow">Chili
<br>
<br>Which of the following car do you like the most?
<br>
<input type="radio" class="required" name="car" value="red">Ferrari
<input type="radio" class="required" name="car" value="blue">Dodge
<input type="radio" class="required" name="car" value="yellow">Chevrolet
<br><br>
<input type="submit" id="submit" class="invalid">
<span class="submit error"></span>
</form>
You can iterate through all the radio buttons that have a name attribute :radio[name] in combination with an array, say examined, that helps you skip buttons that have already been checked. This should be work irrespective of how many sets of radio buttons there are in you form.
$('form').on('input change', function(e) {
e.preventDefault();
var all_selected = true;
var examined = [];
$(':radio[name]').each(function() {
if( examined.indexOf( this.name ) === -1 ) {
examined.push( this.name );
if( !$(':radio:checked[name=' + this.name + ']').length ) {
all_selected = false;
return false;
}
}
});
if( all_selected ) {
//DO STUFF
} else {
//DO OTHER STUFF
}
});
$(function() {
$('form').on('input change', function(e) {
e.preventDefault();
var all_selected = true;
var examined = [];
$(':radio[name]').each(function() {
if( examined.indexOf( this.name ) === -1 ) {
examined.push( this.name );
if( !$(':radio:checked[name=' + this.name + ']').length ) {
all_selected = false;
return false;
}
}
});
if( all_selected ) {
//DO STUFF
console.log( 'All parts completed' );
} else {
//DO OTHER STUFF
console.log( 'Form not complete' );
}
});
});
input {
margin: 7px;
}
.valid {
background-color: green;
border: 3px solid darkgreen;
color: white;
}
.invalid {
background-color: grey;
border: 3px solid darkgrey;
color: black;
}
.error {
color: red;
}
#submit {
display: block;
border-radius: 10px 10px 10px 10px;
width: 130px;
margin: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
Which of the following do you like the most?<br>
<input type="radio" class="required" name="food" value="pizza">Pizza
<input type="radio" class="required" name="food" value="burgers">Burgers
<input type="radio" class="required" name="food" value="Salads">Salads <br><br>
Which of the following colors do you like the most?<br>
<input type="radio" class="required" name="color" value="red">Red
<input type="radio" class="required" name="color" value="blue">Blue
<input type="radio" class="required" name="color" value="yellow">Yellow
<input type="submit" id="submit" class="invalid">
<span class="submit error"></span>
</form>

Categories

Resources