Tabulator: How to get multiline data on separate rows - javascript

I've an object with keys/value pair where values are comma separated in an array.
e.g.
var myObject = { key1 : [v11, v12, v13, v14] , key2 : [v21, v22, v23, v24]};
What I've working now is keys goes in as column headers and all of the array values in single row. The row data appears as comma separated.
I've a mutator that converts "," to "\n" which then converts row data and still shows in single row , albeit on different lines.
What I need is to display each value from each array on separate row , just like in excel. And also (if possible) merge rows for keys for corresponding value rows.
Here's relevant code
<script>
//converts comma to newline
var customMutator = function(value, data, type, params, component){
return value.join("\n");
}
var tableData = [
{id:1, key:"key1", values: ["v11", "v12", "v13", "v14"]},
{id:1, key:"key2", values: ["v21", "v22", "v23", "v24"]},
];
var table = new
Tabulator("#example-table", {
data:tableData,
columns:[
{title:"key", field:"key", formatter:"textarea"},
{title:"values",field:"values", formatter:"textarea", mutator:customMutator,},
],
});
</script>

Because you are only interested in viewing the data and not editing it, the easiest thing is a custom formatter. (If you need to edit the data in that format, then I am not sure how to do that at this time.)
Your custom formatter will create an element with a border for each item in your value array. This is an example of a custom formatter that you could use.
function customFormatter(cell, formatterParams, onRendered) {
const val = cell.getValue();
const cellDiv = document.createElement('div');
for (let i = 0; i < val.length; i++){
const valItemDiv = document.createElement('div');
valItemDiv.textContent = val[i];
valItemDiv.style.border = 'purple 1px solid';
cellDiv.appendChild(valItemDiv);
}
return cellDiv;
}
Here is a full working example. https://jsfiddle.net/nrayburn/sqdvkm5u/11/

Related

Google script loop check for duplicate before writing data

I have a script which reads data from a site, stores the data in an array variable and then writes the data to a google sheet.
Per item id (JSON format), the data which is read is of the form:
[timestamp number text1 text2]
and these details are duplicated across different ids in a for loop.
What i'm left with on the sheet is per row (one item in each cell):
timestamp(id1) number1(id1) text1(id1) text2(id1) timestamp(id2) number1(id2) text1(id2) text2(id2) timestamp(id3) number1(id3)...etc
each row will contain only a single value for timestamp, however the timestamp variable is written multiple times. Is it possible to adapt my script to check column A of the bottom row on my sheet and only write the new row if the timestamp in the current bottom row is different to the timestamp in the new row about to be written.
for loop iterates through json file and stores data in "values" variable.
{
{.....
let values = [];
values.push(timestamp, number1, text1, text2); //final line of for loop
}
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("test");
var range = ss.getRange(3, 1, 1, values.length);
if (range.isBlank()) {
range.setValues([values]);
} else {
ss.appendRow(values);
}
}
2 Requests:
a) I would like the timestamp variable to only be written once, in column A.
b) I would like the script to check the last written row to ensure that the timestamp value printed in column A is different to the value about to be written in the new row. If it is the same, do not write to the row.
Thanks
So for Request A: You need to change the array you are passing to the setValues()method. If you already know which columns these are, then you can modify the array by replacing the existing value with an empty string.
const outputRow = [ … ]; // This is where your current output is set
const emptyTheseColumns = [3, 6, 9]; // columns C, F, I
const cleanedOutputRow = outputRow.map( (item, index) => {
const column = index + 1; // columns start at 1, index at 0
// return empty string for stated columns
if( emptyTheseColumns.indexOf( column ) != -1){
return ""
}
// otherwise return the current value
return item
});
// then use the new array in setValues( cleanedOutputRow )

Read CSV file based on columns

I am working in an Angular js project where I have to read the CSV file column wise using javascript. I have retrieved the CSV and printed it in the console. I am able to split the csv row wise. How to do it based on columns?
Thanks in advance.
CSV is nothing but a 2 dim array. By using 2 for loop you can do.
for example:
for(var i=0;i<col.length;i++){
for(var j=0;j<rows.length;j++){
arr[i][j]
}
}
Interestingly, it sounds easy to parse CSV files but it can get complicated quickly (depending on where your CSV comes from: user-generated, fixed in format from an API, ...):
Parsing headers
Different number of headers and data columns
Delimiter (Germans often use ; instead of ,)
Number format (Germans often use the , instead of . as decimal separators)
Quoted data (maybe with a delimiter inside the quote data)
Whitespace
Line endings
...
That's why there are a lot of CSV parsers available on npm (https://www.npmjs.com/search?q=csv). Some are focused on parsing speed (e.g. https://www.npmjs.com/package/fast-csv) some on convenience (e.g. https://www.npmjs.com/package/papaparse).
But all have in common (as far as I know) that they return row wise. Which is often caused to be able to process streams which will pass the data line wise and not column wise.
Here's a code example to get your data column wise:
const input = `header_1,header_2
value 1,value 2
value 3,value 4`
// get rows -> here \n as line ending is known
const rows = input.split('\n');
// get the first row as header
const header = rows.shift();
// get number of columns by splitting the header
// , as delimiter is known here. Could be different ...
const numberOfColumns = header.split(',').length
// initialize 2D-array with a fixed size
const columnData = [...Array(numberOfColumns)].map(item => new Array());
for(var i=0; i<rows.length; i++) {
var row = rows[i];
var rowData = row.split(',');
// assuming that there's always the same
// number of columns in data rows as in header row
for(var j=0; j<numberOfColumns; j++) {
columnData[j].push(rowData[j]);
}
}
console.log("columnData = " + JSON.stringify(columnData, null, 4));
Output will be:
columnData = [
[
"value 1",
"value 3"
],
[
"value 2",
"value 4"
]
]
Not included is stripping whitespace, converting numbers, ...
For convinience you could use papaparse to get the data row wise and use the nested for loop again:
const Papa = require('papaparse');
// example data with delimiter ; and empty lines
const input = `header_1;header_2
1;"2"
3;4`;
// options for papaparse
const parseOptions = {
quoteChar: '"', // quoting character
delimiter: ';',
skipEmptyLines: true, // ignore empty lines
dynamicTyping: true, // parse numbers automatically
}
const parseResult = Papa.parse(input, parseOptions);
const parsedData = parseResult.data;
// get the first row as header
const header = parsedData.shift();
const numberOfColumns = header.length;
// initialize 2D-array with a fixed size
const columnData = [...Array(numberOfColumns)].map(item => new Array());
for(var i=0; i<parsedData.length; i++) {
var rowData = parsedData[i];
for(var j=0; j<numberOfColumns; j++) {
columnData[j].push(rowData[j]);
}
}
console.log("columnData = " + JSON.stringify(columnData, null, 4));
Output will be:
columnData = [
[
1,
3
],
[
2,
4
]
]

JQuery Datatables Row Data From AJAX Source

In the past I've always used this to get a hidden column's data. I would hide the column with a css class, but the responsive feature doesn't work well with these.
var td = $('td', this);
var ID = $(td[0]).text();
So I found an alternative, by hiding the columns with these classes with the responsive feature.
"columnDefs": [
//Responsive classes
{ className: 'never', targets: 0 }, //Hide on all devices
{ className: 'all', targets: 1 }, //Show on all devices
]
and then I use either one of these.
var rowData = oTable1.fnGetData(this);
var rowData = oTable1.api().row(this).data();
//Grab the first indexed item in the list
var ID = rowData[0];
That works well if you don't have an AJAX source. It will return a comma separated list of the row data. However, when I try to use this with an AJAX source I just get [object Object] back (instead of a comma separated list) if I output the rowData variable in an alert.
How do I get the row data out of a table with an AJAX source?
It seem to be stored as string so [1, 2, 3] became [object Object] when you turn it into string. Do yourString = yourList.join(',') and store yourString to keep the coma-separated string.
For an object:
yourString = (function () {
var list = [];
for(var i in yourList)
if(yourList.hasOwnProperty(i))
list.push(yourList[i]);
return list.join(',');
})();
The function is not needed, it's just to limit the variables scope.
I ended up using an answer I found here.
Converting a JS object to an array
I can pull the entire row data from the table with this.
var rowData = oTable1.api().row(this).data();
In the console log I can see that it returns a javascript object like this.
Object { id="123456", full_name="Samuel Smith", Last_name="Smith" }
I use this function to convert the object into an array.
var array = $.map(rowData, function (value, index) {
return [value];
});
In the console log, my array would appear like this.
["123456", "Samuel Smith", "Smith"]
I can then extract any item from the array like this.
alert(array[0]);
Simplifying madvora's example:
var rowData = oTable1.api().row(this).data().to$();
rowDataArray = rowData.toArray();

Get data from table column and make individual array and 2 dimensional array also using jquery

I have to make an array which is fetching data from a table column one which is a text and 5th is value using jQuery and data is input dynamically. Array size is not fixed, and also need make 2 dimensional array using both column. Actually I have to make a chart so column 1 is giving name and column 2 is giving his ownership and data can be varied in each column. I have tried many code I am sending all but I am not getting anything at all:
var nameArray = [];//this should be 1 dimenional containing name as ['user1', 'user2', 'user3', 'user4', 'user5'];
var ownArray = new Array();//this should be 1 dimenional containing ownership as [parseInt(u1), parseInt(u2), parseInt(u3), parseInt(u4), parseInt(u5)];
var namenown = new Array();//this should be 2 dimensional array containg name and ownership as ['user1', parseInt(u1)], ['user2', parseInt(u2)], ['user3', parseInt(u3)];
['user4', parseInt(u4)], ['user5', parseInt(u5)]
$("#resourceUserDetails tbody tr:nth-child(1)").each(function () {
nameArray.push($(this).text());
//(tr).find('td:eq(2)').text();
//alert($(tr).find('td:eq(2)').text());
//var names = ['"' + nameArray.join('", "') + '"'];
});
$('#resourceUserDetails tbody tr:nth-child(5)').each(function () {
ownArray.push($(this).value());
});
$.each(nameArray, function (index, value) {
debugger;
alert(nameArray[index]);
debugger;
});

make json from table

I want to make specific json from table. I have a table, which has rows and 4 columns.
Here is my table I want to build an jsonarray from the table.
First value in the left column is key of json and last value in the right column is a valueof json.
I mean I want to get from table jsonarray, it must look as
json_from_form = [{color: 'id',
name: "mouse",
x: "table",
y: "book"}];
I have tried to build json, but have a problem with structure and setting a key in json object.
Please help me to buld right structure of json object.
var json_from_form_tmp = {};
$('#table').find('tbody tr').each(function (i) {
//var name = $(this).find('td:first').text();
json_from_form_tmp[i] = {
imd: $(this).find('td:eq(3) input').val()
};
});
console.log(json_from_form_tmp);
Here is my DEMO
You should use the jQuery map-function for this, here is an example:
$(function () {
var m = $("table tr").map(function (index, e) {
return {
color: $(e).children().eq(0).text(),
name: $(e).children().eq(1).text()
}
}).get();
});
Where m will be an array of objects as defined inside the map function.
To set a property of the object (json_from_form_tmp), use the ['propertyName'] notation.
//get the name of the property from the first column
var name = $(this).find('td:first').text();
//use that name as the name of the property. Your value fetch was right!
json_from_form_tmp[name] = $(this).find('td:eq(3) input').val();
Here is your fiddle with a tiny modification.
http://jsfiddle.net/bMzq8/32/

Categories

Resources