Iterating through Array of Objects to fill input fields - javascript

I am currently working on a workaround for Google Forms which will be able to store all inputs in cookies so a user can proceed the survey at a different time.
At the moment I am able to store all questions (a Question is a object that contains: id of the surrounding div, required, userinput in a cookie by using JSON.stringify(). I am also able to read and parse the cookie which gets me an array of all question objects.
Now I want to fill all fields or check all radio buttons which have a value.
My problem is, that the inner for loop does only 2 iterations but it should do 18. Do you have any idea what could be wrong?
function restoreInputs() {
// number of stored cookies
var countCookies = 27;
console.log(countCookies);
// iterate through all cookies
for (var i = 1; i < countCookies + 1; i++) {
var cookiename = "answer" + i;
// get content of cookie (is array of objects)
var answer = checkCookie(cookiename);
// iterate through content
for (var j = 0; j < answer.length; j++) {
// get value of object
var val = answer[j].value;
// get the input field (textarea or radio button)
var x = document.getElementById(answer[j].n).getElementsByTagName('input');
// if input is radio, then check the one at position stored in value of object
if (x[j].type === "radio") {
x[val].checked = true;
// if textarea set its value to the one stored in object value
} else {
x[j].value = val;
}
console.log("j: " + j);
}
}
console.log(i);
}

I found the solution. The problem was that I forgot a for loop, since var x = document.getElementById(answer[j].n).getElementsByTagName('input'); may return more than one element. So here is the solution:
function restoreInputs() {
// number of stored cookies
var countCookies = 27;
console.log(countCookies);
// iterate through all cookies
for (var i = 1; i < countCookies + 1; i++) {
var cookiename = "answer" + i;
// get content of cookie (is array of objects)
var answer = checkCookie(cookiename);
// iterate through content
for (var j = 0; j < answer.length; j++) {
// get value of object
var val = answer[j].value;
// get the input field (textarea or radio button)
var x = document.getElementById(answer[j].n).getElementsByTagName('input');
// if input is radio, then check the one at position stored in value of object
for (var k = 0; k < x.length; k++) {
if (x[k].type === "radio") {
x[val].checked = true;
// if textarea set its value to the one stored in object value
} else {
x[k].value = val;
}
}
console.log("j: " + j);
}
}
console.log(i);
}

Related

javascript for loop for json variables in localStorage only displays last item in wtform

I'm trying to populate a wtform textareafield with items from a json array stored in localStorage. There should be 1 value on each line like this:
value1
value2
value3
when I get the items with my for loop only the last item is displayed.
value3
Any assistance would be greatly appreciated.
function getValue() {
//sets requirements as a json array
var myinputs = $("[id^=reqInput]").map(function(){
return this.value;
}).get();
localStorage.setItem("reqs", JSON.stringify(myinputs));
console.log(myinputs);
// calls arrays and populates criteria form
for (var i = 0; i < myinputs.length; i++) {
var reqArray = myinputs[i];
console.log(reqArray);
document.getElementById("mission").value = reqArray;
};
};
From your code, the statement below will always replace the previous value with the new one on each loop:
document.getElementById("mission").value = reqArray;
If you want each value to be printed in separates line, you need to append the value on the #mission (not replacing it), and put <br /> in between.
Example:
// empty the element at first
document.getElementById("mission").innerHTML = ""
for (var i = 0; i < myinputs.length; i++) {
var reqArray = myinputs[i];
document.getElementById("mission").innerHTML += reqArray + "<br />";
};
I made the following adjustments based of feedback from Noval Agung Prayogo and it works perfectly!
function getValue() {
//sets requirements as a json array
var myinputs = $("[id^=reqInput]").map(function(){
return this.value;
}).get();
sessionStorage.setItem("reqs", JSON.stringify(myinputs));
console.log(myinputs);
document.getElementById("mission").value = ""
for (var i = 0; i < myinputs.length; i++) {
var reqArray = myinputs[i];
document.getElementById("mission").value += reqArray + '\n';
};
};

undefined parameter in js

I am receiving a type error stating that the array testA[i] is undefined whenever I add an input into the html page. I have the array set and i'm trying to add the value of currency to the array using the push method to add to the second part of the array i.e([0][currency])
function Test() {
var testA = [];
for (i = 0; i < 4; i++) {
this.currency = prompt("Please enter a 3-letter currency abbreviation", "");
testA[i].push(currency);
}
}
var index = new Test();
any help as to why the array is undefined would be appreciated.
Note: I have now tried both testA.push(currency) and testA[i] = this.currency, and I still get the same error as before.
Note: the final version should have it loop through 4 different questions asked and each time adding these into an array. At the end of the loop a new variant of the array should be made and the new set of data entered will be added to it. something like
for(i = 0; i < 4; i++) {
testA[i] = i;
for(j = 0; j < 4; j++) {
this.currency = prompt("Please enter a 3-letter currency abbreviation", "");
testA[i][j] = this.currency;
}
}
but at this point in time I'm just trying to get it to work.
You don't use the push method on a index. You use it on the array itself.
Replace this
testA[i].push(currency);
With this
testA.push(currency);
You need to perform push operation on the array directly.
testA.push(currency);
By executing testA[index] you will receive hold value. In JS it will always return undefined, if index is greater than array length.
Because your array is empty as the beginning, you are always receiving undefined.
You are mixing up two different implementation.
Either you use direct assignation.
var testA = new Array(4);
for (i = 0; i < 4; i += 1) {
this.currency = prompt('...', '');
testA[i] = this.currency;
}
Either you push new values into the array.
var testA = [];
for (i = 0; i < 4; i += 1) {
this.currency = prompt('...', '');
testA.push(this.currency);
}
You should use the second one, which is the most simple soluce.
testA[i] = this.currency OR testA.push(this.currency)
Use Modified function below
function Test() {
var testA = [];
for (i = 0; i < 4; i++) {
this.currency = prompt("Please enter a 3-letter currency abbreviation", "");
testA[i] = this.currency; // use this.currency here if you
}
console.log(testA);
}
var index = new Test();

Object Not Maintaining Assigned Values

I am looping through an array to create another array of objects in a modified format.
for (i = 1; i <= 37; i++) { // create 37 boxes for days of the month and nearby dates
room_reservations[i] = {};
var this_date = getDate();
var res_count = 0;
for (var res_index = 0; res_index < reservations.length; res_index++) {
var this_res = reservations[res_index];
// bad assignment location
// res_room = JSON.parse(JSON.stringify(this_res));
if (this_res.checkin <= this_date && this_res.checkout > this_date) {
for (var k = 0; k < this_res.rooms.length; k++) {
var res_room = {};
res_room = JSON.parse(JSON.stringify(this_res));
var this_room = res_room.rooms[k];
res_room.room_index = k;
var traveler_count = this_room.travelers.length;
console.log('traveler_count: ', traveler_count);
res_room.traveler_count = traveler_count;
//traveler_counts[i][res_room.room_name] = traveler_count;
console.log('res_room.traveler_count: ', res_room.traveler_count);
var room_name = this_room.room_name;
console.log('room_name: ', room_name);
res_room.room_name = room_name;
console.log('res_room: ', res_room);
room_reservations[i][res_room.room_name] = res_room;
}
}
}
}
Essentially, I console log the object property traveler_count and get the correct value. But when logging the entire object, the property value is incorrect. It's like it grabs the value from the next loop.
How do I fix this? It is not just the logging. The values being set are wrong in the room_reservations array. For example, I set the attribute name to res_room.room_name and the value to res_room. But the attribute name does not match the value in the object.
Please help. Thx
The problem is that you're using the same res_room object every time through the for (var k) loop. So all the properties in res_room[i] are referring to the same object, which you modify in place. You need to make a copy of the object when you assign it.
room_reservations[i][res_room.room_name] = JSON.parse(JSON.stringify(res_room));

Output an Array using a for loop

I need to create an Array asking the user for 5 values to enter.
They must enter city names (strings) and I need to create that using a for loop.
Then I need to output that information using another for loop.
Here is what I have so far:
//Declare the variables
var cities= array(SIZE);
var SIZE = 5;
var index = 0;
var BR = "<br />";
// Create the for loop to prompt the user
for(index = 0; index < SIZE ; index++) {
cities= prompt("Please enter the cities!");
}
//Output the array information
for( /* ? */ ) {
document.write(cities[SIZE]+ " was the city you entered" + BR);
}
I don't know what to put between the for() to output that information. Is there a better way to do this?
The main problem is that you're not adding to the cities - you're replacing the array with a string, each time through the loop. You want to use push() instead.
And don't output cities[SIZE] - that will be past the end of the array. Loop through (just like on input) and output cities[index].
//Declare the variables
var SIZE = 5;
var cities = new Array(SIZE); // JS is case-sensitive
var index = 0;
var BR = "<br />";
//Create the for loop to prompt the user
for (index = 0; index < SIZE; index++) {
cities[index] = prompt("Please enter the cities!");
}
//Output the array information
for (index = 0; index < SIZE; index++) {
document.write(cities[index] + " was the city you entered" + BR);
}
Paul is right. In the first loop you directly set cities variable to the input entered by the user. Also you don't need to set the Array size. Best practice is to use brackets. Shortened version could be:
//Declare the variables
var size = 5,
cities = [];
//Create the for loop to prompt the user
for (var index = 0; index < size; index++) {
cities.push(prompt("Please enter the cities!"));
}
//Output the array information
for (var index in cities) {
document.write(cities[index] + " was the city you entered <br />");
}

Search Box Function Not Eliminating Correct Value

I am trying to make a simple website where the user types input into a search box, and every time a key is press, their input is compared against the first row of a 2 dimensional array which checks for character matches. If the character they input doesn't match anything, I want it to remove that specific bucket of the array. I have attempted to write basic code for this I thought would work, and have it up at the demo site linked. (Sorry I am just using a free host and havn't optimized the equation table at all so bear with it)
http://fakefakebuzz.0fees.net/
As you can see, the function is not eliminating the appropriate table rows. For example, typing "A" should not eliminate the "Average Current Equation" row because the first letter of that is A, which means matches should not = 0.
I have been looking through this code all morning, and cannot find where I went wrong. I also want to stick to vanilla js.
Any help?
Thanks so much.
I just debugged your code, and the function you use is narrowTable. first remove onkeypress from body node
<body onload="printTable()" onkeypress="narrowTable()">
and add onkeyup instead to you input, like this:
<input type="search" name="equationSearch" id="equationSearch"
placeholder="Equation Search" autofocus="" onkeyup="narrowTable()">
because when you use onkeypress the key value hasn't been added to the input box and your input value has no value in your function, which is:
function narrowTable() {
var newTableContent = "";
var matches = 0;
var input = document.getElementById("equationSearch").value;
//input has no value
for (var i = 0; i < tableData.length; i++) {
for (var j = 0; j < tableData[i][0].length; j++) {
if (input == tableData[i][0].charAt(j)) {
matches++;
}
}
if (matches == 0) {
tableData.splice(i, 1);
}
matches = 0;
}
for (var i = 0; i < tableData.length; i++) {
newTableContent += "<tr><td>" + tableData[i][0] + "</td><td>" + tableData[i][1] + "</td></tr>";
}
document.getElementById("table").innerHTML = newTableContent;
}
the other problem your code has is after printing your table, your tableData variable has changed because you have removed some of indexes. you should reset the tableData to its original value or you can do:
function narrowTable() {
//create a copy of your original array and use currenttableData instead
var currenttableData = tableData.slice();
var newTableContent = "";
var matches = 0;
//your code
}
the other problem here is the way you search for your input value:
for (var j = 0; j < tableData[i][0].length; j++) {
if (input == tableData[i][0].charAt(j)) {
matches++;
}
}
if (matches == 0) {
tableData.splice(i, 1);
}
you can easily do this, instead:
if(tableData[i][0].search("input") == -1){
tableData.splice(i, 1);
}
First, to check if a string is a substring of another string, you can use indexOf. It will return -1 if the string is not found in the other string.
Second, you shouldn't alter the array while you are still looping through it, unless you make sure to alter the counter variable (i in this case) appropriately.
var dataToRemove = [],
i;
for (i=0; i<tableData.length; i++) {
if(tableData[i][0].indexOf(input) == -1) {
// add the index to the to-be-removed array
dataToRemove.push(i);
}
// remove them in reverse order, so the indices don't get shifted as the array gets smaller
for(i = dataToRemove.length - 1; i >= 0; i--) {
tableData.splice(i, 1);
}
dataToRemove = [];
for (i=0; i<tableData.length; i++) {
newTableContent += "<tr><td>" + tableData[i][0] + "</td><td>" + tableData[i][1] + "</td></tr>";
}
I haven't tested this code, but it should at least give you a better idea of how to make this work.

Categories

Resources