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">
Related
I have multiple inputs as an array like this:
<input name="data[extras][1][id]" value="1">
<input name="data[extras][1][netto]">
<input name="data[extras][1][tax]">
<input name="data[extras][1][brutto]">
<input name="data[extras][2][id]" value="2">
<input name="data[extras][2][netto]">
<input name="data[extras][2][tax]">
<input name="data[extras][2][brutto]">
i got all extras with:
let extras = $('input[name^=data\\[extras\\]]');
now i would like to iterate through all to create an array out of it but i need for the id for further actions (the 1 or the 2).
i would like to achive something like this:
let id = $('input[name^=data\\[extras\\]\\[UNKNOWN ID\\]\\[id\\]]').val();
i hope anybody can help me.
Greetings
you can receive all ids in jquery like this
$('document').ready(function(){
var values = $('input[name$=\\[id\\]]').map(function(){return $(this).val();}).get();
console.log(values); });
Maybe you could loop trough the inputs and in the loop get the id/index via regexp from the name attribute to query that [id] input?
data\[extras\]\[(\d)\]
Unclear what your expected output would be, but you can easily loop over the collection of elements and parse out the number and the string.
var inputs = document.querySelectorAll('[name^="data\[extras\]"]');
const grouped = Array.from(inputs).reduce(function(o, input) {
const parts = input.name.match(/^data\[extras\]\[(\d+)\]\[(.*)\]$/);
const index = parts[1];
const key = parts[2];
o[index] = o[index] || {};
o[index][key] = input.value;
return o;
}, {});
console.log(Object.values(grouped))
<input name="data[extras][1][id]" value="1-i">
<input name="data[extras][1][netto]" value="1-n">
<input name="data[extras][1][tax]" value="1-t">
<input name="data[extras][1][brutto]" value="1-b">
<input name="data[extras][2][id]" value="2-i">
<input name="data[extras][2][netto]" value="2-n">
<input name="data[extras][2][tax]" value="2-t">
<input name="data[extras][2][brutto]" value="2-b">
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 ;)
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/
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.
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