Pushing an array into another array - nested - javascript

I am creating a store. The way it works is that when I click 'add to cart', I run a function which gets the id of the button. From that id, you can work out the name of the product, get the cost, quantity etc. For simplicity, this is the funciton code:
function getID(a){
var id = a.substring(0, a.length - 4);
var id_quant = document.getElementById(id + '_val').value;
var id_name = document.getElementById(id + '_nme').innerHTML;
console.log(id + " " + id_quant + " " + id_name);
}
You may notice that I remove the last 4 digits from this.id, this is because when I run the PHP to echo all the results, i make the button_id equal to the uid from the database, concatenated with _btn.
What I would then like to do is to push this into an array, or use JSON.
What I am imagining is a nest array like : array[uid][cost], array[uid][name]. I'm just not sure how to do this.
It should be noted that in the function, a is actually this.id:
<button id='1_btn' onclick='getID(this.id)'></button>
I have declared an array above the function, var array = [].
Any help on how to push a nest would be great.

What I would then like to do is to push this into an array, or use
JSON.
You need to use an object
var obj = {};
and set values in this obj from the function as
function getID(a){
var id = a.substring(0, a.length - 4);
var id_quant = document.getElementById(id + '_val').value;
var id_name = document.getElementById(id + '_nme').innerHTML;
obj[ id ] = { quantity : id_quant, name : id_name }; //observe this line
console.log(id + " " + id_quant + " " + id_name);
}

instead of array you should have an object.
var bucket = {};
bucket[someuid] = {
"cost": 500,
"name": "Some Item"
}
Now you can access this simply by,
console.log(bucket[someuid]);
Iterating then is simple
for (item in bucket){ console.log(item['name'], item['cost']) }

Related

JavaScript Looping Variables on Left Side of Equal Sign

I'm looping through results and writing them out to html.
I want to increment the number 1 on the lest side of the equal sign - the binding -
A_Inside_Bus_1_div, A_Inside_Bus_2_div, A_Inside_Bus_3_div etc..
How should I go about that?
for (var i = 0; i <= 4; i++) {
A_Inside_Bus_1_div.innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
A_Inside_Bus_1_Comments_div.innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
Do it like this:
var A_Inside_Bus_div = [];
var A_Inside_Bus_Comments_div = [];
Before you continue the rest, like editing .innerHTML, you need to create those objects. Only after that you can do something like:
for (var i = 0; i <= 4; i++) {
A_Inside_Bus_div[i].innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
A_Inside_Bus_Comments_div[i].innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
This is just an idea how you "should go" about that, as you said.
If those variables are actually the IDs of DIVsm and you're depending on the fact that IDs are turned into global varables, you can use document.getElementById() to access them.
for (var i = 0; i <= 4; i++) {
document.getElementById('A_Inside_Bus_' + (i+1) + '_div').innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
document.getElementById('A_Inside_Bus_' + (i+1) + '_Comments_div').innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
Don't do this. Trying to make variable names to do what you're trying to do just leads to needlessly messy code down the road.
Stick all your elements into arrays:
var elems = [
A_Inside_Bus_1_div
A_Inside_Bus_2_div
...
];
var comments = [
A_Inside_Bus_1_Comments_div
A_Inside_Bus_2_Comments_div
...
];
Then just index the arrays:
for (var i = 0; i <= 4; i++) {
elems[i].innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
comments[i].innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
This is an example of how you could do it with your current setup. Note though, it could be cleaned up. If each element of the elems array always has a partner in comments, it would make more sense to group them together in an object, and only have 1 array.
Also note that populating the arrays in a loop makes more sense. I just hardcoded the arrays here for the sake of brevity. I'm not sure how you're creating the elements originally. They should probably be created and put straight into the array instead of naming them and adding them later.
There are a couple ways you could go about doing this, but they tend to involve some pretty bad habits, like using eval or attaching variables to the global object so you can access them with a string:
var a = 1;
window['a']; //1
But there are better alternatives, the most common is probably storing them in equal-length arrays:
var divs = [div1, div2, div3];
var items = ['cat', 'dog', 'fish'];
items.forEach(function(element, index){
divs[index].innerText = items[i];
});
You could also look at building out a single array of objects:
var objects = [{div: div1, item: 'cat'}, {div: div2, item: 'dog'}, {div: div3, item: 'fish'}];
for object in objects {
object.div.innerText = object.item;
}

How to iterate through an array containing objects - javascript

I have an array containing objects that looks like this:
[{\"user\":\"mcnewsmcfc\",\"num\":11},{\"user\":\"ManCityFNH\",\"num\":7}];
I am then using:
var jsonu = JSON.parse(tweets.replace(/"/g, '\"'));
to remove all the unwanted characters from the array. My question is then how to iterate through the array and (EDIT) use the values of "user" and "num" for each object in the table (EDIT).
This is what I initally have but this does not extract the correct values:
for (var u in jsonu) {
var row = $('<row></row>');
row.append('<th>' + jsonu[u][0] + '</th><td>' + jsonu[u][1] + '</td>');
$('#userTable').append(row);
}
var tweets = '[{\"user\":\"mcnewsmcfc\",\"num\":11},{\"user\":\"ManCityFNH\",\"num\":7}]';
var jsonu = JSON.parse(tweets.replace(/"/g, '\"'));
for (var u in jsonu) {
var row = $('<row></row>');
row.append('<th>' + jsonu[u].user + '</th><td>' + jsonu[u].num + '</td>');
$('#userTable').append(row);
}
since jsonu is an array, u is just the index in the array. jsonu[u] will return back the object at that index in the array, which is a javascript object.
So to access the user and num property, simply call jsonu[u].user and jsonu[u].num

How can I group data returned in JSON format and return it?

I have a JSON string of the form:
[
{"ID":153,"CircuitID":53,"StartTime":"2014-11-12 12:45:00","EventFormatID":224,"TotalPlaces":8,"BookedPlaces":0,"ProvisionalPlaces":0},
{"ID":161,"CircuitID":53,"StartTime":"2014-11-12 17:15:00","EventFormatID":224,"TotalPlaces":0,"BookedPlaces":0,"ProvisionalPlaces":0},
{"ID":734,"CircuitID":53,"StartTime":"2014-11-12 18:30:00","EventFormatID":231,"TotalPlaces":14,"BookedPlaces":0,"ProvisionalPlaces":0}
]
In place of Event Format ID and Circuit ID I will be returning the names
What I need to do is group the results by Event Format ID and return the results in the following format:
Event 224 : 12:45 (8 places available), 17:15 (0 places available)
Event 231 : 18:30 (14 places available)
I can't seem to figure out how to loop through the data, group it by Event Format ID to present it in the required format!
Thanks
Can you use any additional libraries? I'd use lo-dash which would make this relatively simple:
var grouped = _.groupBy(data, "EventFormatID");
_(grouped).forEach(function (group, key) {
console.log("Event:" + key);
_(group).forEach(function (course) {
console.log(course.StartTime + " (" + course.TotalPlaces + " places available)");
});
});
Obviously the example above logs to the console but it'd be fairly simple to change to build up whatever string or object you need.
This is easier with lodash/underscore, or even with ES5 array and object methods, but since you asked about pure JS:
var data = {}, results = [], i, j, id, time, obj, evts; // obj is your object above
for (i=0; i<obj.length; i++) {
id = obj[i].EventFormatID;
time = obj[i].StartTime; // you can simplify to get just the time, not the datetime, if you prefer
data[id] = data[id] || [];
data[id].push({"time":time,"places":obj[i].TotalPlaces});
}
// now you have a proper data structure, just print it out
for (i in data) {
if (data.hasOwnProperty(i)) {
// just show the output properly formatted
evts = [];
for (j=0;i<data[i].length;j++) {
evts.push(data[i][j].time+" ("+data[i][j].places+" places available)");
}
results.push("Event "+i+" : "+evts.join(","));
}
}
ES5 makes this so much easier
var data = {}, results = [], obj; // obj is your object above
obj.forEach(function(val,i) {
data[val.EventFormatID] = data[val.EventFormatID] || [];
data[val.EventFormatID].push({"time":val.StartTime,"places":val.TotalPlaces});
});
// now you have a proper data structure, just print it out
Object.keys(data).forEach(function(key) {
var value = data[key], evts = [];
value.forEach(function(elm) {
evts.push(elm.time+" ("+elm.places+" places available)");
});
results.push("Event "+key+" : "+evts.join(","));
});
And lodash is even easier.
Please take a look that:
http://jsfiddle.net/m260n5ud/
html
<div id="contentDiv"></div>
js
function tidyUp(jsonArray) {
var myObject = {};
for (i = 0; i < jsonArray.length; i++) {
var key = jsonArray[i]['EventFormatID'];
var time = jsonArray[i]['StartTime'].replace(' ', ':').split(/[- :]/);
time = time[3] + ":" + time[4];
var totalPlace = jsonArray[i]['TotalPlaces'];
if (myObject[key] == null) {
myObject[key] = "Event : " + key + " : " + time + " ( " + totalPlace + " places available)";
} else {
myObject[key] += ", " + time + " ( " + totalPlace + " places available)";
}
}
console.log(myObject);
for (var k in myObject) {
document.getElementById('contentDiv').innerHTML += myObject[k] + "<br/>";
}
}

How to create an array of variables from an array in Javascript

I have a variable called "information" which creates a multi-dimensional array. For each row in the array, I want to return a variable whose name is the first value in the array. In other words, given the 'information' array below, I'd want the following output:
var lunalovegood = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Luna Lovegood is a Ravenclaw!;
var dracomalfoy = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Draco Malfoy is a Slythering!;;
var hermionegranger = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Hermione Granger is a Gryffindor!;;
In other words, I want to be able to work with each of the elements in the 'information' array to create some markup. I already know how to get the information I need given the information array, but as you can see below I'd have to declare separate variables for each of the names.
for (var i = 0; i < information.length; i++) {
var htmlString = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i] [1] + '!'; //Luna Lovegood is a Ravenclaw!
$('div').html(htmlString);
} //end for loop
var information = [
['lunalovegood', 'Ravenclaw', 'Luna', 'Lovegood', '(chaser)', 'lovegood.jpg', 4]
['dracomalfoy', 'Slytherin', 'Draco', 'Malfoy', '(seeker)', 'malfoy.jpg', 2],
['hermionegranger', 'Gryffindor', 'Hermione', 'Granger', '(none)', 'granger.jpg', 3],
];
The javascript below creates three variables called 'lunalovegood', 'dracomalfoy', and 'hermionegrange', but it's the long way of creating variables. How do I create these variables, one for each row in the array, by looping through the 0th indexed element in the 'information' array?
var myVariables = {}
,varNames = ["lunalovegood","dracomalfoy","hermionegranger"];
for (var i=0;i<varNames.length;i+=1){
myVariables[varNames[i]] = 0;
console.log(lunalovegood);
}
Your current approach just needs a most minor tweak to not require the second array.
var students = {}, i;
for (i = 0; i < information.length; ++i)
students[information[i][0]] = information[i][2] + ' ' + information[i][3] + ' is a ' + information[i][1] + '!';
Now the key is set by taking the first item of the Array. You would then do the following for your text,
students['lunalovegood']; // "Luna Lovegood is a Ravenclaw!"
You're also missing a , in your information literal.
This should help you:
Every variable in the global scope can be accessed as a string property of the window object
var myvariable = 4;
alert(window["myvariable"]); // will alert 4
window["newvariable"] = 6;
alert(newvariable); // will alert 6
I agree with Bergi. Variables should represent a fixed finite set of members defined by code; data (as in the contents of a list) should generally not introduce new variables.
As such, here is the approach I would recommend (note that I've added a bit more than the "minimum required"; good luck!):
// Using a function makes it easy to change details and avoid leaking
// variables accidentally.
function loadWizards(information) {
var wizards = [];
for (var i = 0; i < information.length; i++) {
var info = information[i];
var name = info[0];
// Mapping to named properties means we can forget about indices!
wizards[name] = { // <- use Name to map to our Wizard object
house: info[1],
// ..
image: info[7]
};
}
return wizards;
}
// I have no idea if they are wizards, but give variables useful names.
// 'information' is too generic.
var wizards = loadWizards(information);
// Then later on, use it as:
alert("Hello " + wizards['hermionegranger'].name + "!")
// ^-- property access by Name
var formattedInfo = {};
$.each(information, function (i, v) {
formattedInfo[v[0]] = v[2] + ' ' + v[3] + ' is a ' + v[1];
});
there is a missing comma at the end of the 1st line of your definition of information.
BTW, I like Harry Potter very much.

adding multiple values to single array item in javascript

I am having trouble with output of an array, I think.
What I would like the output to look like is:
1. FirstName LastName DOB
but what I end up with is:
1. FirstName
2. LastName
3. DOB
Here is what I have so far but I am not seeing what I am doing wrong.
// global variable:
var tasks = [];
// Function called when the form is submitted.
// Function adds a task to the global array.
function addTask() {
'use strict';
// Get the task:
var firstName = document.getElementById('firstName');
var lastName = document.getElementById('lastName');
var dob = document.getElementById('dob');
// numerical value of dob
var dateofBirth = new Date(dob.value);
// Reference to where the output goes:
var output = document.getElementById('output');
// For the output:
var message = '';
if (firstName.value && lastName.value && dob.value) {
// Add the item to the array:
tasks.push(firstName.value, lastName.value, dateofBirth.toString());
// Update the page:
message = '<h2>Persons Entered</h2><ol>';
for (var i = 0, count = tasks.length; i < count; i++) {
message += '<li>' + tasks[i] + '</li>';
}
message += '</ol>';
output.innerHTML = message;
} // End of IF.
// Return false to prevent submission:
return false;
} // End of addTask() function.
// Initial setup:
function init() {
'use strict';
document.getElementById('theForm').onsubmit = addTask;
} // End of init() function.
window.onload = init;
Thanks, I hope this helps you to help me.
tasks.push({firstName: firstName.value, lastName: lastName.value, DOB: dateofBirth.toString()})
And then
tasks[0].firstName will output firstName.value
tasks[0].lastName will output lastName.value
etc..
Edit
Using this, you can then construct your messasge like this :
for (var i = 0, count = tasks.length; i < count; i++) {
message += '<li><span>' + tasks[i].firstName + '</span><span> '
+ tasks[i].lastName + '</span><span>' + tasks[i].DOB + '</span></li>';
}
Of course, the span tags are optionnal but this will allow you to apply a style to each part of the information in your css (width, padding, etc..) and you will always be able to easily select a property of a task by index
Your problem is that you're adding li elements to every element in your array, instead only add teh li once
// Update the page:
message = '<h2>Persons Entered</h2><ol><li>' + tasks.join(' ') + '</li></ol>';
output.innerHTML = message;
Why do you put each element in its own <li>?
If you don't put it in different <li> but in a common one, everything will be fine
message = '<h2>Persons Entered</h2><ol><li>';
for (var i = 0, count = tasks.length; i < count; i++) {
message += tasks[i];
message += " ";
}
message += '</li></ol>';
output.innerHTML = message;
Use Span. you can use Array.join
output.innerHTML= '<h2>Persons Entered</h2><div><span>' + tasks.join("</span> <span>") +"</span>";
You want to add them as an array to the array, not as values to the array
What you have is this:
tasks.push(firstName.value, lastName.value, dateofBirth.toString());
what I think you want is this:
tasks.push([firstName.value, lastName.value, dateofBirth.toString()]);
The answer above is the same, but with an object, not a array.
What you are doing is pushing multiple values into your array. What you want to be doing is to turn the different values into a single value and then push that value into your array. To get the exact output as you were requesting, you can turn these multiple values into one by concatenating them into a string:
Change this:
tasks.push(firstName.value, lastName.value, dateofBirth.toString());
Into this:
tasks.push(firstName.value + ' ' + lastName.value + ' ' + dateofBirth.toString());
However, this does mean you'll lose access to the individual values. If you want access to those, you could instead assemble them into an object:
tasks.push({"firstName" : firstName.value,
"lastName" : lastName.value,
"dateOfBirth" : dateofBirth.toString());
Its a little confusing what you are asking. If you simply want this:
1. FirstName LastName DOB
over this:
1. FirstName
2. LastName
3. DOB
Then your issue is not with the array but with how you are defining the loop code. Try this instead:
// Update the page:
message = '<h2>Persons Entered</h2><ol><li>';
for (var i = 0, count = tasks.length; i < count; i++) {
message += tasks[i] + ' ';
}
message += '</li></ol>';
That way you are putting the array elements in a single list element, rather than across three of them.
EDIT - for Multi-dimensional array traversal
This is assuming that the array is defined this way (per Dan Steingart's answer):
tasks.push([firstName.value, lastName.value, dateofBirth.toString()]);
We then can have the following:
// Update the page:
message = '<h2>Persons Entered</h2><ol>';
for (var i = 0, count = tasks.length; i < count; i++) {
message += '<li> + tasks[i].toString().replace(',',' ') + '</li>';
}
message += '</ol>';
Here you are traversing each element of tasks when each element of tasks is also itself an array. The toString() on an inner array will display the values in a comma separated fashion, then the replace() function simply replaces the comma's with spaces.

Categories

Resources