creating a dynamic binding in JavaScript - javascript

I'm implementing a feature which will allow me to dynamically add columns into a JavaScript table:
for(var i = 0; i < info.length; i++){
var temp = [];
temp.push(parseInt(info[i].site_id));
temp.push(info[i].site);
temp.push(info[i].site_code);
temp.push(processArray(info[i].tc10));
temp.push(processArray(info[i].tc9x_test));
temp.push(processArray(info[i].tc9x_build));
temp.push(processArray(info[i].oracle_dev));
temp.push(processArray(info[i].database));
temp.push(processArray(info[i].baseline));
temp.push(processArray(info[i].push_windows));
temp.push(processArray(info[i].push_unix));
temp.push(processArray(info[i].license));
temp.push(processArray(info[i].tcx));
temp.push(processArray(info[i].eng));
temp.push(processArray(info[i].perforce_proxy));
temp.push(processArray(info[i].volume_server));
temp.push(info[i].windows_ref_unit_location);
temp.push(info[i].unix_ref_unit_location);
temp.push(info[i].windows_rte_location);
temp.push(info[i].unix_rte_location);
temp.push(info[i].windows_toolbox_location);
temp.push(info[i].unix_toolbox_location);
temp.push(info[i].UGII_LICENSE_FILE);
temp.push(info[i].UGS_LICENSE_SERVER);
temp.push(info[i].unix_dev_units);
temp.push(info[i].unix_devop_path);
temp.push(info[i].perforce_proxy_path);
temp.push(info[i].primary_contact);
temp.push(info[i].secondary_contact);
temp.push(info[i].num_users);
temp.push(info[i].TC_12);
// check if new columns got added:
if(len > 29){
for(var j = 30; j < len; j++){
var col = columns[j];
temp.push(info[i].col);
}
}
rows.push(temp);
}
return rows;
}
var rows = [[]] holds the table data ... info[[]] contains the JSON objects queried from the database.
The problem in on this piece of code:
for(var j = 30; j < len; j++){
var col = columns[j];
temp.push(info[i].col);
}
I'm trying to dynamically bind col with some of the attributes of info. But I don't know whether is possible or not ... How could I do that?
Suppose a user added a new column, TC_12. Thus, I don't know TC_12 exists, so I want to dynamically bid col into info[i] so it could somehow yield me info[i].TC_12.
Any ideas?

Use square bracket notation to use the value of a variable or the result of some other expression as the object property.
temp.push(info[i][col]);
FYI, you can do all those pushes with a single call to .push() by passing multiple arguments...
temp.push(parseInt(info[i].site_id),
info[i].site,
info[i].site_code,
processArray(info[i].tc10),
processArray(info[i].tc9x_test),
// etc...
);

Related

Transferring data by date from email

I'm fairly new to coding in Google Script, and with Javascript. Basically what I'm trying to do is make a script to update data on a table in a spreadsheet. I have the script to import the email as a CSV, but I'm struggling with transferring the data from the email to the table by matching up the dates. Essentially what I would like the script to do is emulate a vlookup and paste the values from the emails CSV file to the table.
I made a copy of the file as an example of what I'm trying to do. I'm trying to transfer the yellow section of columns A and B of the Data tab to the matching yellow section columns A and B. And if there is no data for the dates then I would like the empty dates to be 0.
https://docs.google.com/spreadsheets/d/1uK3sCUFvcW6lgk962jgTN-yZox-lF8-Z0wm7Zhh-i8I/edit?usp=sharing
Thanks!
This two functions will accomplish your objectives. createArray(hight, width, filling) is just a workaround to create an array of the exact size of the Destination table. moveDates() is the one that compares the timestamps of the Data table with the ones on Destination; and will write down the values of the row if they match, and a zero if they don't.
This second function will first declare a bunch of variables that will save ranges and values for both sheets. After that, it will read all the dates of both tables. Later, it will run through the Destination table searching for coincidences and saving them on the newData array. Finally, the code will write down the newData. I've tested this code on your spreadsheet and it works perfectly.
function createArray(hight, width, filling) {
var array = [];
for (var i = 0; i < hight; i++) {
array[i] = [];
for (var j = 0; j < width; j++) {
array[i][j] = filling;
}
}
return array;
}
function moveDates() {
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');
var destinationSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(
'Destination');
var dataRange = dataSheet.getRange(5, 1, 6, 3);
var destinationRange = destinationSheet.getRange(2, 1, 11, 3);
var newDataRange = destinationSheet.getRange(2, 2, 11, 2)
var data = dataRange.getValues();
var destination = destinationRange.getValues();
var dataDates = [];
var destinationDates = [];
var newData = createArray(11, 2, 0);
for (var i = 0; i < data.length; i++) {
dataDates.push(new Date(data[i][0]));
}
for (var i = 0; i < destination.length; i++) {
destinationDates.push(new Date(destination[i][0]));
}
for (var i = 0; i < destination.length; i++) {
for (var j = 0; j < data.length; j++) {
if (destinationDates[i].getTime() === dataDates[j].getTime()) {
newData[i][0] = data[j][1];
newData[i][1] = data[j][2];
}
}
}
newDataRange.setValues(newData);
}
If you need more information or clarifications I'll be happy to help you.

JavaScript - Dynamic Array and Looping

Imagine you have a product page. On this page there are two select inputs with options in them.
There is one for Size and Colour. This can change depending on the product, e.g. a curtain might have a size, length and colour (three select menus).
The array is created dynamically (based on each select menu and its options):
var dynamicArr = [],
i,
j,
opt,
$('.select');
for (i = 0; i < select.length; i += 1) {
opt = select.eq(i).find('option');
if (dynamicArr[i] === undefined) {
dynamicArr[i] = [];
}
for (j = 0; j < opt.length; j += 1) {
dynamicArr[i].push(opt.eq(j));
}
}
Imagine the page had a size and colour drop-down. The above would create an array like this:
dynamicArr = [['size'], ['color']]
I want to loop through each of these separately (in order to get individual values and compare them).
My problem starts here. A dynamic array might have a length of 1, 2, 3, 4, 5, 6 (depending on the select options on the page). I therefore can't do this as there won't always be two selects
for (i = 0; i < dynamicArr[0].length; i += 1) {
}
for (i = 0; i < dynamicArr[1].length; i += 1) {
}
How would I go about finding out the length and looping individually like the above e.g. if there are three selects, it will automatically know there are this many and loop through them like above.
If you are still confused, let me know.
Thanks.
You can always use Array.forEach
dynamicArr.forEach(function(el){
console.log(el);
});
I hope I didn't get you wrong, but here's a solution:
for(i = 0; i < dynamicArr.length; i++) {
for(j = 0; j < dynamicArr[i].length; j++) {
// do something here..
}
}
you should try something like this:
dyn.forEach(function(el){//dyn is the dynamic array
console.log(el); //logs to console
});

which is faster in a for loop, accessing values using temp variable or the index?

I am trying to optimize some knockout js code and I was wondering which would be faster, ie accessing the variable using the indexer as so:
for (var i = 0; i < data.length; i++) {
data[i].MediaID = ko.observable(data[i].MediaID);
data[i].MediaName= ko.observable(data[i].MediaName);
data[i].MediaTypeID= ko.observable(data[i].MediaTypeID);
}
or declaring a temp variable.
for (var i = 0; i < data.length; i++) {
var temp = data[i];
temp.MediaID = ko.observable(temp.MediaID);
temp.MediaName= ko.observable(temp.MediaName);
temp.MediaTypeID= ko.observable(temp.MediaTypeID);
}
Accesing with the temp-variable should be slightly faster because you don't need to look up the element in the array.
However, the gain will be minimal
compare
data.a.b.c.d.e.f.g.MediaID = ko.observable(data.a.b.c.d.e.f.g.MediaID);
data.a.b.c.d.e.f.g.MediaName= ko.observable(data.a.b.c.d.e.f.g.MediaName);
data.a.b.c.d.e.f.g.MediaTypeID= ko.observable(data.a.b.c.d.e.f.g.MediaTypeID);
and
var temp =data.a.b.c.d.e.f.g;
temp.MediaID = ko.observable(temp.MediaID);
temp.MediaName= ko.observable(temp.MediaName);
temp.MediaTypeID= ko.observable(temp.MediaTypeID);
you don't need to look up the same thing so many times
if you want it faster you should also cache data.length
for(var i = 0, len = data.length; i < len; i++)...
If you are concerned about performance don't use array.length in the loop. That is not a value, is a internal function that everytime that is accessed recount the total items of the array, the better is:
var total = items.length;
for(i=0; i < total; i++){
//stuff
}
Now for your specific use case, I do not know the framweworks that you are using on, but if you are using jQuery and / or underscore, instead of a loop, you could use one of the map functions:
http://api.jquery.com/jQuery.map/
http://underscorejs.org/#map

how to access and sort 2d array in javascript

I'm writing a script to initalize 2d array in javascript by reading txt file. Here are some portions of my code
var neighbor = {};
var temp = new Array();
neighbor[nodemap[ temparray[0]]] = temp; //nodemap[ temparray[0]] is an integer
neighbor[nodemap[temparray[0]]]. push(nodemap[temparray[1]]);
neighbor[nodemap[temparray[0]]]. push(nodemap[temparray[2]]);
.... // continue to add value
Then I want to access and sort the array, like this
for (var i = 0; i < n_count; i++);
{
for (var k = 0; k < neighbor[i].length; k++);
neighbor[k].sort(function(a,b){return a - b})
}
However, I got the error that neighbor[i] is unidentified. Could you please show me how to fix that?
Your neighbor "array" is actually an object literal. So the way you should loop over neighbor is:
for (var key in neighbor) {
var cur = neighbor[key];
cur.sort(function (a,b) {
return a - b;
});
}

Loop through radio buttons on a form using a construted variable name

I have several radio buttons on a form all grouped in 3's, and when they are clicked I need to run a JS function on them. In this function I loop through the radio buttons in the group of the button that was pressed (i.e. if the group was called 'abc_name' id use for (var i = 0; i < form.abc_name.length; i++){ }).
I'm wondering if there is a way to action a group of radio buttons in the same way using a constructed group name? For example if I passed 'xyz' to the function I'd need the code to be for (var i = 0; i < form.xyz_name.length; i++){ }. Thanks.
Use square bracket notation.
function loopDeLoop (xyz) {
var elems = form.elements[xyz + "_name"],
len = elems.length,
i;
for (i=0;i<len;i++){
console.log(elems[i];
}
}
You should really be using getElementsByName() in both cases;
for (var els = document.getElementsByName(xyz + '_name'), i=0; i<els.length;i++) {
// something on els[i]
}
Although the direct equivalent for what you've got would be:
for (var els = form.elements[xyz + "_name"];, i=0; i<els.length;i++) {
// something on els[i]
}
Use [] property syntax:
function loop(s) {
s += '_name';
var inputs = form[s];
for (var i = 0; i < inputs.length; ++i) {
...
}
}
This is necessary when the property key is a variable - a.b syntax only works if b is a "literal".

Categories