How to remove unchecked value from list? - javascript

I need to get all checked values from checkboxes and return them in element.
I have a code:
this.values = [];
if (item.checked) {
this.values.push(item.value);
} else {
this.values.splice(item.value)
}
return alert(this.values);
There are few problems:
If I check and uncheck the same item, it pushes to array every time, so there could be same multiple values. (this.values = [1,1,1])
Splice does not remove from this.values one item.value that was unchecked, it removes all values and make this.values empty (this.values = []);
What I need is:
if I have item values for example: 1 , 2 , 3
And check every item, that my array will become - this.values = [1 , 2 , 3]
If I uncheck item number 2, this.values = [1, 3]

Use a common class for all the checkbox, then use document.querySelectorAll to get the checkbox and attach event listener to each of the box.
Now on change even call another function and first filter out the checked checkbox then use map to get an array of the check box value
let elem = [...document.querySelectorAll('.checkBox')]
elem.forEach(item => item.addEventListener('change', getChecked))
function getChecked() {
let getChex = elem.filter(item => item.checked).map(item => item.value)
console.log(getChex)
}
<input type="checkbox" value="1" id="one" class="checkBox">
<label for="one">1</label>
<input type="checkbox" value="2" id="two" class="checkBox">
<label for="two">2</label>
<input type="checkbox" value="3" id="three" class="checkBox">
<label for="three">3</label>

Ciao, you can do this:
this.values = [];
if (item.checked) {
if(!this.values.includes(item.value)) {
this.values.push(item.value);
}
} else {
if(indexOf(item.value) !== -1){
this.values.splice(this.values.indexOf(item.value), 1)
}
}
return alert(this.values);
Insert item.value only if this.values does not contains value and use splice with index (if item is in this.value).

since you didn't show your html file. I just posted the code works for me for your reference.
function getSelectedCheckboxValues(name) {
const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
let values = [];
checkboxes.forEach((checkbox) => {
values.push(checkbox.value);
});
return values;
}
if you are editing js in the HTML,
replace
const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
with
const checkboxes = document.querySelectorAll('input[name="color"]:checked');
source: https://www.javascripttutorial.net/javascript-dom/javascript-checkbox/

Related

How to amalgamate an array of Nodelists into a single array

I have a function that takes elements from the DOM to update a db on button click. Currently, there is one id for one value...
<input class='total' doc-id='12345678' value='${whateverCurrent.value}'>user updates</field>
<input class='total' doc-id='87654321' value='${whateverCurrent.value}'>user updates</field>
This is the function:
const elements = document.querySelectorAll('.total')
await Promise.all(Array.from(elements).map(async (el) => {
let docId = el.id;
let total = el.value;
await updateDoc(docId, { total });
}))
I now need to break this down such that there are 4 classes of input fields rather than 1 (by quarter). So there will be different elements but with the same id:
<input class='q1' doc-id='12345678' value='${whateverCurrent.value}'>user updates</field>
<input class='q2' doc-id='87654321' value='${whateverCurrent.value}'>user updates</field>
<input class='q2' doc-id='12345678' value='${whateverCurrent.value}'>user updates</field>
I could run the Promise.all function 4 times, once for each class, but that must be wrong, when instead I should somehow....
// (do something here){
await updateDoc(docId, {q1, q2, q3, q4})
}
when I take all the elements and put them into an array and look at them in the console, I get an array of 4 NodeLists.
How do I take these 4 nodeLists and amalgamate them so that every id has its 4 values to pass to the update function?
I'm not really sure if this is what you're looking for. Can you be more specific in what the updateDoc function expects as arguments?
Anyway, I coded something that collects all the quarterly values per doc-id and produces an object of following form:
{
1234 :
{
q1 : 7
q2 : 9
},
...
}
const elements = document.querySelectorAll('input')
const docsPerQ = {};
elements.forEach(e => {
const docId = e.getAttribute('doc-id');
const val = e.value;
const quarter = e.className;
if(!(docId in docsPerQ)) docsPerQ[docId] = {};
docsPerQ[docId][quarter] = val;
});
console.log(docsPerQ);
<input type="text" class="q1" value="7" doc-id="1234">
<input type="text" class="q1" value="2" doc-id="5678">
<input type="text" class="q2" value="3" doc-id="5678">
<input type="text" class="q2" value="9" doc-id="1234">
EDIT
I changed the code a bit so the produced output is in a more manageable form. It's now an array of objects with some extra keys attached:
[
{
docId: 1234,
quarters: {
q1: 7,
q2: 3
}
},
...
]
const elements = document.querySelectorAll('input');
const QsPerDoc = [];
elements.forEach(e => {
const docId = e.getAttribute('doc-id');
const val = e.value;
const quarter = e.className;
const entry = QsPerDoc.find(e => e.docId === docId);
// find returns undefined if nothing's found. undefined is a falsy value
if(!entry) {
let quarters = {};
quarters[quarter] = val;
QsPerDoc.push({
docId : docId,
quarters
});
}
else {
entry.quarters[quarter] = val;
}
});
console.log(QsPerDoc);
<input type="text" class="q1" value="7" doc-id="1234">
<input type="text" class="q1" value="2" doc-id="5678">
<input type="text" class="q2" value="3" doc-id="5678">
<input type="text" class="q2" value="9" doc-id="1234">
Maybe this works better? Hope it does. I wonder, is the updateDoc function something you can change so it can accept arrays?
You could access them like this:
console.log(QsPerDoc[0].docId);
console.log(QsPerDoc[0].quarters.q1);
(Note: I also changed the name of the object/array to QsPerDoc instead of DocsPerQ, which was not aplty named)
Anyway I have to get back to work instead of procrastinating on stackoverflow ;)

html checkboxes associative array - how to access this array in javascript?

I'm trying to do this:
<input type="checkbox" name="appliances[microwave]">
<input type="checkbox" name="appliances[coffee-machine]">
<input type="checkbox" name="appliances[grill]">
and get access to this array in javascript like this
1.
var myarr = document.getElementsByName('appliances');
alert('here ' + myarr);
result: alert shows "here [object NodeList]"
2.
var myarr = document.getElementsByName('appliances');
alert('here ' + myarr['grill']);
result: alert shows "here undefined"
How may I get access to this array?
Your elements all have different names as far as HTML is concerned, "appliances[microwave]", "appliances[coffee-machine]", etc. Those names are only special to certain software (for instance, PHP will handle them on a form submission).
You can find all elements whose name starts with appliances by using querySelectorAll with the selector input[name^=appliances]. Then you access the entries in that NodeList by index (0, 1, and 2):
const checkboxes = document.querySelectorAll("input[name^=appliances]");
for (let n = 0; n < checkboxes.length; ++n) {
console.log(`${checkboxes[n].name} checked? ${checkboxes[n].checked}`);
}
<input type="checkbox" checked name="appliances[microwave]">
<input type="checkbox" name="appliances[coffee-machine]">
<input type="checkbox" name="appliances[grill]">
<!-- A fourth one just to show that it won't get selected: -->
<input type="checkbox" name="something-else">
If you want to access them by the names in [], you could create an object and put them on the object as properties:
function getNamedElementObject(baseName) {
const result = {};
// NOTE: The next line assumes there are no `]` characters in `name`
const list = document.querySelectorAll(`[name^=${baseName}]`);
for (const element of list) {
const match = element.name.match(/\[([^]+)\]/);
if (match) {
const propName = match[1]
result[propName] = element;
}
}
return result;
}
const checkboxes = getNamedElementObject("appliances");
console.log(`checkboxes["microwave"].checked? ${checkboxes["microwave"].checked}`);
console.log(`checkboxes["coffee-machine"].checked? ${checkboxes["coffee-machine"].checked}`);
console.log(`checkboxes["grill"].checked? ${checkboxes["grill"].checked}`);
// You could also loop through by getting an array from `Object.values`:
for (const checkbox of Object.values(checkboxes)) {
console.log(`${checkbox.name} checked? ${checkbox.checked}`);
}
<input type="checkbox" checked name="appliances[microwave]">
<input type="checkbox" name="appliances[coffee-machine]">
<input type="checkbox" name="appliances[grill]">
<!-- A fourth one just to show that it won't get selected: -->
<input type="checkbox" name="something-else">
Or you could use a Map:
function getNamedElementMap(baseName) {
const result = new Map();
// NOTE: The next line assumes there are no `]` characters in `name`
const list = document.querySelectorAll(`[name^=${baseName}]`);
for (const element of list) {
const match = element.name.match(/\[([^]+)\]/);
if (match) {
const propName = match[1]
result.set(propName, element);
}
}
return result;
}
const checkboxes = getNamedElementMap("appliances");
console.log(`checkboxes.get("microwave").checked? ${checkboxes.get("microwave").checked}`);
console.log(`checkboxes.get("coffee-machine").checked? ${checkboxes.get("coffee-machine").checked}`);
console.log(`checkboxes.get("grill").checked? ${checkboxes.get("grill").checked}`);
// You could also loop through via the iterator from the `values` method:
for (const checkbox of checkboxes.values()) {
console.log(`${checkbox.name} checked? ${checkbox.checked}`);
}
<input type="checkbox" checked name="appliances[microwave]">
<input type="checkbox" name="appliances[coffee-machine]">
<input type="checkbox" name="appliances[grill]">
<!-- A fourth one just to show that it won't get selected: -->
<input type="checkbox" name="something-else">

Store multiple checkbox inputs in local storage

I have multiple checkbox inputs that look like this:
<input type="checkbox" id="box-1">
<input type="checkbox" id="box-2">
<input type="checkbox" id="box-3">
I want to store their values (checked or unchecked) in the browser's local store.
The javascript that I'm using to do this is:
function onClickBox() {
let checked = $("#box-1").is(":checked");
let checked = $("#box-2").is(":checked");
let checked = $("#box-3").is(":checked");
localStorage.setItem("checked", checked);
}
function onReady() {
let checked = "true" == localStorage.getItem("checked");
$("#box-1").prop('checked', checked);
$("#box-2").prop('checked', checked);
$("#box-3").prop('checked', checked);
$("#box-1").click(onClickBox);
$("#box-2").click(onClickBox);
$("#box-3").click(onClickBox);
}
$(document).ready(onReady);
The first part saves the checkbox's state on the click and the second part loads it when the page refreshes.
This works well if the lines for box 2 and 3 are removed, but I need it to work with all the checkboxes.
Your main issue here is that you're only storing a single value in localStorage, checked, which will be overwritten every time you check a different box. You instead need to store the state of all boxes. An array is ideal for this, however localStorage can only hold strings, so you will need to serialise/deserialise the data when you attempt to read or save it.
You can also simplify the logic which retrieves the values of the boxes by putting a common class on them and using map() to build the aforementioned array. Try this:
<input type="checkbox" id="box-1" class="box" />
<input type="checkbox" id="box-2" class="box" />
<input type="checkbox" id="box-3" class="box" />
jQuery($ => {
var arr = JSON.parse(localStorage.getItem('checked')) || [];
arr.forEach((c, i) => $('.box').eq(i).prop('checked', c));
$(".box").click(() => {
var arr = $('.box').map((i, el) => el.checked).get();
localStorage.setItem("checked", JSON.stringify(arr));
});
});
Working example
function onClickBox() {
let checked1 = $("#box-1").is(":checked");
let checked2 = $("#box-2").is(":checked");
let checked3 = $("#box-3").is(":checked");
localStorage.setItem("checked1", checked1);
localStorage.setItem("checked2", checked2);
localStorage.setItem("checked3", checked3);
}
function onReady() {
let checked1 = "true" == localStorage.getItem("checked1");
let checked2 = "true" == localStorage.getItem("checked2");
let checked3 = "true" == localStorage.getItem("checked3");
$("#box-1").prop('checked', checked1);
$("#box-2").prop('checked', checked2);
$("#box-3").prop('checked', checked3);
$("#box-1").click(onClickBox);
$("#box-2").click(onClickBox);
$("#box-3").click(onClickBox);
}
$(document).ready(onReady);
Of course you could simplify it further by doing
function onClickBox(boxNumber) {
let checked = $("#box-" + boxNumber).is(":checked");
localStorage.setItem("checked" + boxNumber, checked);
}
function onReady() {
[1, 2, 3].forEach( function(boxNumber) {
$("#box-" + boxNumber).prop(
'checked',
localStorage.getItem("checked" + boxNumber)
);
$("#box-" + boxNumber).click( function() {
localStorage.setItem(
"checked" + boxNumber,
$("#box-" + boxNumber).is(":checked")
);
});
})
}
$(document).ready(onReady);
Your check variable is getting overwritten, you can put it inside for loop.
So your code becomes,
function onClickBox() {
for(var i=1;i<=3;i++){
let checked=$("#box-"+i).is(":checked");
localStorage.setItem("checked-"+i, checked);
}
}
function onReady() {
for(var i=1;i<=3;i++){
if(localStorage.getItem("checked-"+i)=="true"){
var checked=true;
}
else{
var checked=false;
}
$("#box-"+i).prop('checked', checked);
onClickBox();
}
}
$(document).ready(onReady);
Please follow the below Code (Very Simple Javascript works)
<input type="checkbox" id="box">checkbox</input>
<button type="button" onClick="save()">save</button>
<script>
function save() {
var checkbox = document.getElementById("box");
localStorage.setItem("box", checkbox.checked);
}
//for loading...
var checked = JSON.parse(localStorage.getItem("box"));
document.getElementById("box").checked = checked;
</script>
with simple modification, you can use it without save button..
Hope this Helps you..

javascript multidimensional array creation and insertion

Hello I want to create an array in javascript
var sortValues = array(
2 => array(3,4,5),
3 => array(5,6,7),
12 => array (7,4,5)
);
Now I am looping through all textboxes of my form. Every textbox has id like 2_3 means 2 will be the main index of the array.
My html markup looks like
<input type="text" value="3" id="2_5" name="2_5">
<input type="text" value="4" id="2_5" name="2_6">
<input type="text" value="5" id="2_5" name="2_7">
<input type="text" value="5" id="3_1" name="3_1">
<input type="text" value="6" id="3_2" name="3_2">
..................................
Now I want to check if 2 exists in array sortValues, I will take the value of the text box and and will check if this value exists in the array against 2 then I will put an alert that value already exists, if value doesn't exists push the value in sub array. Means I need to put 3 against 2 I will check if 3 exists against 2, if yes put alert else push in array.
If 2 (main index) doens't exist create a new index in array and so on. I have tried so far
var sortvalues = new Array();
$(":text").each(function () {
if($(this).val() != '') {
id = $(this).attr('id');
ids = id.split("_");
parent = ids[0];
child = ids[1];
if(typeof sortvalues[parent] !== 'undefined') {
if(typeof sortvalues[parent][$(this).val()] !== 'undefined') {
alert("Value already exists");
} else {
sortvalues[parent][] = $(this).val();
}
} else {
sortvalues.push(parent);
}
}
});
console.log(sortValues);
Which gives ["2", "2", "2"] which is wrong. Can Any body guide me how can I achieve above mentioned array in above mentioned criteria ??/
Do you mean to create an array in another array?
For example :
var sortValues = new Array();
sortValues[2] = Array(3,4,5);
Please clarify your question. And the following:
sortvalues[parent][] = $(this).val() --> you can't leave empty for the second array.

Select all radio buttons which are checked with prototype

I have several input elements which look like this:
<input type="radio" checked="checked" value="1" name="handle[123]" />
<input type="radio" checked="checked" value="2" name="handle[456]" />
The number inside the name attribute is an object id i need. Now what I want to do is:
Fetch all input which are of type="radio" and are checked with prototype
Put all ids and values in an associative array
...so the resulting array looks something like this:
array{ 1 => 123, 2 => 456 }
Any ideas?
Here's what I came up with:
var results = [];
document.body.select('input[type=radio]:checked').each(function (element) {
var object = {};
object[element.value] = element.name.match(/\d+/)[0];
results.push(object);
});
new Ajax.Request('/some_url', {
method: 'post',
parameters: results
});
Demo
To get the checked radio button given a form id, and the name of the radio group:
function RF(el, radioGroup) {
if($(el).type && $(el).type.toLowerCase() == 'radio') {
var radioGroup = $(el).name;
var el = $(el).form;
} else if ($(el).tagName.toLowerCase() != 'form') {
return false;
}
var checked = $(el).getInputs('radio', radioGroup).find(
function(re) {return re.checked;}
);
return (checked) ? $F(checked) : null;
}
var value = RF('form_id', 'radio_grp_name');
Hope it helps
$$('input:checked[type=radio]').each(function (ele) {
output[ele.name.match(/\d+/)[0]] = ele.value;
});
This would give the desired output using prototype

Categories

Resources