storing table cell content into js array - javascript

I need to store table cell content into array using tr and td indexes like this:
myArray[tr_idx][td_idx]='value';
It is not required to store data of all of cells in array but only several with a special content, but if i use indexes as a keys of the array i'll have many empty array elements.
e.g.
myArray[2][3]='data1';
myArray[4][3]='data2';
alert (myArray.toSource()) -> [, , [, , , "data1"], , [, , , "data2"]]
maybe there is another suitable way of storing such type of data?

Why not just store them as individual 2-item arrays [row,col]? Since the table cells are already accessible via tableElement.rows[].cells[], you can use the 2 indices to access them from the table.
var storedCells = [];
// Store row 2, column 3
storedCells.push([2,3]);
Access with:
// Table row:
storedCells[0][0]
// Table column
storedCells[0][1]
//As in :
tableElement.rows[storedCells[0][0]].cells[storedCells[0][1]].innerHTML = "New cell value!"
Or even cleaner, if you prefer to use objects rather than arrays:
storedCells.push({row: 2, column: 3});
storedCells.push({row: 4, column: 6});
Accessed with:
tableElement.rows[storedCells[0].row].cells[storedCells[0].column].innerHTML = "New cell value!";
Finally, if you don't actually need the row/column indexes, but rather the DOM nodes themselves, just push those onto your array.
var storedCells = [];
// Save references to some individual <td> nodes
storedCells.push(tableElement.rows[1].cells[2]);
storedCells.push(tableElement.rows[4].cells[6]);
They are then trivially modified:
// Set the value of the second element:
storedCells[1].innerHTML = "New content!";
Update after comment:
If you need to be able to attach the cell coordinates to a new value from the backend, a good solution would be to expand the object {} example above to include a value attribute. The server can pass back the new value in JSON.
storedCells.push({row: 2, column: 3, value: ""});
storedCells.push({row: 4, column: 6, value: ""});
Your backend should send a JSON response back to the script containing the same type of array of objects, where value: has been populated with the new cell value. You can then pass it back into the table with:
// Pass the value attribute received from JSON into the cell's contents
tableElement.rows[storedCells[0].row].cells[storedCells[0].column].innerHTML = storedCells[0].value;

Not sure if this is the right answer but you could try to check if cells are empty before pushing them into the array. In the loop place a an if statement that will check the value of the cell and compare it to the value you require. This way you should end up with just an array of value and no empties. But you may need to record the index as well then.

Related

Copy a specific column from a csv file to an array using javascript

I have a little problem that is how to Copy a specific column from a csv file to an array using javascript
thank you :)
csv data is best represented in javascript using an array of arrays (a 2-dimension array) with primary indices representing rows (records in data-base terminology) and the inner indices representing column cells for that row (fields in data-base terminology).
Thus, this csv data:
"name","age","height"
"John",22,1.9
"Jane",21,1.9
"Joe",23,1.8
would be represented as:
[["name","age","height"],["John",22,1.9],["Jane",21,1.9],["Joe",23,1.8]];
in a javascript array.
If you have an array like that, you can extract a column (the first column, inner array index [0] in this case, easily with:
const columnArray = [];
for (let i=0; i<csvArray.length; i++){columnArray.push(array1[i][0])}
// columnArray now holds ["name","John","Jane","Jo"];
// use [1] instead of [0] for the second column, [2] for the third, etc.;
If you don't yet have the array, you will have to form one. Many frameworks may do this for you but it is easily achieved once you have the csv data inside a variable:
const csvFileData = // read from textarea or file;
const csvArray = csvFileData.split('\n')
// csvArray holds ['"name","age","height"', '"John",22,1.9', '"Jane",21,1.9', '"Joe",23,1.8'] at this stage;
// split the inner arrays to arrays of cell data;
for (let i=0; i<array1.lengthl; i++){array[i]=array[i].split(',')}
// We've replaced each element with an array holding the component cells of what was previously a row;
// csvArray now holds:
[["name","age","height"],["John",22,1.9],["Jane",21,1.9],["Joe",23,1.8]];
That final array can now be processed to extract the required column as shown above.
Finally, all this assumes you can get the csv data into a variable (remember it has line breaks). Fetch() is probably the standard way but a simple (if dirty) alternative I often use is to assign the value of an html textarea into which I have pasted the csv file contents into, directly to a variable:
const csvFileData = document.getElementById('textareaOnWebPage').value;

Cannot get values of a column with getRange and getValues

Here is the code I have so far:
var items = data.getRange(1,14,1,lc).getValues()[0];
var names = cdata.getRange(52, 1, 28,1).getValues()[0];
When I log 'items' I get the desired information populated in a single array.
When I try to get the 'names' in a column using a similar method I can only get the first cell in a single array or all of the desired cells in an array of arrays.
example of items
[item1,item2,item3,...]
example of names
[name1] or [[name1],[name2],[name3],[...]]
Why am I not able to use the same method to accurately retrieve the names in a column as I did in the row? How do I fix this and get the desired result? How do I get names to return the data in the cells as I did with items?
I see you have 1 column for names combined with []. That will return a [] result from a a structure like [ [][][] ] (not [ [] ]). If your items have multiple rows, you'll get the entire first row [,,,], as you suggest in items.
var items = data.getRange(1,14,1,lc).getValues()[0];
var names = cdata.getRange(52, 1, 28,1).getValues()[0];
That's more a diagnosis than an answer. Basically, you're getting what you should get from that, but I think you want it transposed. Various ways to do that.
But will this work?
// flatten(flatten()) works for 2-level nesting, and so on
function flatten(arrayOfArrays){
return [].concat.apply([], arrayOfArrays);
}
reference: https://gist.github.com/MauricioMoraes/225afcc9dd72acf1511f
You will have to use this instead:
var names = cdata.getRange(52, 1, 28,1).getValues().flat();

Extract JSON table from JSON string element

I get this JSON in response from server:
{
"tab":[
"[[\"2018\",11,\"19\",\"16\",\"13\"],null,null,null,null,null,\"40\"]",
"[[\"2018\",11,\"19\",\"16\",\"19\"],null,null,null,null,null,\"56\"]",
"[[\"2018\",11,\"19\",\"16\",\"21\"],null,null,null,null,\"57\",null]"
]
}
I know, that I can get first element of tab table returned using $.tab[1]. The returned element is a string that holds a table - first element of this table is another table holding a date. The question is what JSON Path expression should I use in order to extract year value from the inner table or one of those numbers at the end (40, 56, 57)?
I'm not sure what you mean when you say you can get the first element with $.tab[1]. Are you using jQuery? Even so, that doesn't seem to make any sense. Regardless, you can parse those inner tables and access them normally as arrays:
var results = {
"tab":[
"[[\"2018\",11,\"19\",\"16\",\"13\"],null,null,null,null,null,\"40\"]",
"[[\"2018\",11,\"19\",\"16\",\"19\"],null,null,null,null,null,\"56\"]",
"[[\"2018\",11,\"19\",\"16\",\"21\"],null,null,null,null,\"57\",null]"
]
};
// you can refactor this as a method for more convenient usage, this is just a demo
var row = JSON.parse(results.tab[0]);
// now you just have a multi-dimensional array, use it as normal
console.log(row[0][0]); //year
console.log(row[6]); //number

Accessing the input field data as table data and pull it in objet

I am creating an array object from the table format.
I have 5 columns, out of which 4 & 5th columns are input text elements. Whatever I modify or update, those should reflect in array object which I am constructing from table.
sample JS code is given below & eq(3) which is 4th element is returning an empty value, even if I have modified the text value in it.
var json = [];
$('#MyTable').find('tbody tr').each(function(){
// document.querySelector
var obj = {},
$td = $(this).find('td'),
key = $td.eq(0).text(),
val = $td.eq(3).text();
obj[key] = val;
json.push(obj);
});
How to get the input value in my object construction?
To get data from the input box, you would need to look for the input's ID, and then use .value on that.
What I would instead recommend is to use <td contenteditable=true>. This will make your table value itself editable by the user. Such a feature has been in use since IE 5.5, Safari, Firefox 3, and Opera 9, so it should be suitable for your project.

ComboBox.store.loadData can't load single-item array

I am using ExtJS 3.4 .
I have a structure with data for combobox like this:
var a = [[1,"text1"],[2,"text2"]]
I load it like this:
ComboBox.store.loadData(a);
But when I have only 1 item in the array
var a = [[1,"text1"]]
then it doesn't load at all. I've read that:
an Array : Arrays will be converted to a Ext.data.ArrayStore
internally, automatically generating field names to work with all data
components. 1-dimensional array : (e.g., ['Foo','Bar']) A
1-dimensional array will automatically be expanded (each array item
will be used for both the combo valueField and displayField)
2-dimensional array : (e.g., [['f','Foo'],['b','Bar']]) For a
multi-dimensional array, the value in index 0 of each item will be
assumed to be the combo valueField, while the value at index 1 is
assumed to be the combo displayField.
But that doesn't explain how do I load an array with one element. Or whatever, it shouldn't be necessary an array, the point is to load only one item. I've tried loading this:
Code:
[{id:1,text:"text1"}]
[[{id:1,text:"text1"}]]
{id:1,text:"text1"}
Even creating a custom ArrayStore:
Code:
var store = new Ext.data.ArrayStore({
autoDestroy: true,
storeId: 'Store1',
idProperty:"id",
fields: ["id","text"]);
ComboBox.store = store;
ComobBox.store.loadData([{id:1,text:"text1"}]);
But everything loads incorrectly . Either the combobox is empty, or it displays id instead of text.
I can see that if I lazily init the combo:
Code:
{"xtype":"combo","width":250,"fieldLabel":"my combo","value":31029,"forceSelection":true,"hiddenName":"ComboHiddenName","minChars":1,"triggerAction":"all","store":[[31029,"gdfs"]]}
then the array with one item will load successfully. At which properties of ComboBox.store should I look to configure them properly for a single-item array to be loaded correctly using loadData method?
ComboBox.store.loadData(var a); would not work for any data. It would raise exception Unexpected token var. Instead one should use ComboBox.store.loadData(a); without var
ComboBox.valueField = "id";
ComboBox.displayField = "text";
ComboBox.store = new Ext.data.ArrayStore({autoDestroy: true, fields: ["id", "text"]});

Categories

Resources