generate array of merged cells handsontable - javascript

for example i have an array of rows:
{ "name1", "value1", "other1", "another1" },
{ "name1", "value2", "other2", "another2" },
{ "name2", "value3", "other3", "another3" },
{ "name2", "value4", "other4", "another4" }
i cant generate the array that will have the structure of merged cells like:
{ row: 0, col: 0, colspan: 1, rowspan: 2 },
{ row: 2, col: 0, colspan: 1, rowspan: 2 }
where row is row index, col column index, colspan is span of columns and rowspan is the span of rows on table.
so far i have the code:
var prev;
var entry = {};
var repeat = 1;
var result = [];
for(a in data){
if(a>0){
prev = data[a-1];
for(b in data[a]){
if(prev[b]===data[a][b]){
if(repeat==1){
entry["row"] = a-1;
entry["col"] = b;
entry["colspan"] = 1;
}
repeat++;
}
}
}
}
but i cant understand when i can make rowspan=repeat then make repeat=1, again and at the same time i need to push this entry inside the result
thank you all for the help!
EDIT: I've managed to do almost working example, but with little mistake, it doesnt push the last merge... any ideas to make it push the last entry?!
var cols = data[0].length;
var prev;
var entry = {};
var repeat = [];
for(var i=0;i<cols;i++){
repeat.push(1);
}
var result = [];
for(a in data){
if(a>0){
prev = data[a-1];
for(b in data[a]){
if(prev[b]!=null&&prev[b]===data[a][b]){
if(repeat[b]==1){
entry["row"] = a-1;
entry["col"] = parseInt(b);
entry["colspan"] = 1;
}
repeat[b]++;
}else{
if(repeat[b]>1){
entry["rowspan"] = repeat[b];
result.push(entry);
repeat[b] = 1;
entry = {};
}
}
}
}
}
it is clear that my structure has a minus in that it is using the prev variable and starts from second row... but i didnt come up with any other better way.

So i figured out how i can do it :) here is my code, just in case if someone will need it. Not the best way thou... but it works!
var cols = data[0].length;
var prev;
var entry = {};
var repeat = [];
for(var i=0;i<cols;i++){
repeat.push(1);
}
var result = [];
for(a in data){
if(a>0){
prev = data[a-1];
for(b in data[a]){
if(prev[b]!=null&&prev[b]===data[a][b]){
if(repeat[b]==1){
entry["row"] = a-1;
entry["col"] = parseInt(b);
entry["colspan"] = 1;
}
repeat[b]++;
}else{
if(repeat[b]>1){
entry["rowspan"] = repeat[b];
result.push(entry);
repeat[b] = 1;
entry = {};
}
}
}
if(a==data.length-1){
for(var i=0;i<repeat.length;i++){
if(repeat[i]>1){
entry["rowspan"] = repeat[i];
result.push(entry);
repeat[i] = 1;
entry = {};
}
}
}
}
}

Related

How to change csv to json array using javascript

I want to add an external CSV file into a JOSN Array in my JS Code.
I tried lots of codes, with no luck like this:
var map = {};
var rows = csv.split(/\n/g);
var keys = rows.shift().split(",");
rows.forEach(raw_row => {
var row = {};
var row_key;
var columns = raw_row.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
columns.forEach((column, index) => {
var key = keys[index];
if (!key) return;
if (key === 'Name') {
row_key = column;
return;
}
if (key === "Coordinates") {
column = column.replace(/""/g, '"');
column = column.substring(1, column.length - 1);
column = column.replace(/([a-zA-Z_]+):/g, `"$1":`);
try {
column = JSON.parse(`{${column}}`);
} catch (e) {}
}
row[key] = column;
});
map[row_key] = row;
});
console.log(map);
but I believe my expectation is something else, so I dont get what I want.
could some one pleae help me to change this csv(file):
contry;fromNr;toNr;Type;cust_1;cust_2
US;0;100;wood;max;nuk
DE;100;500;metal;max;pal
into JSON Array:
[{
"country": "US",
"fromNr": 0,
"toNr": 100,
"Type": "wood",
"cust_1": "max",
"cust_2": "nuk"
}, {
"country": "DE",
"fromNr": 100,
"toNr": 500,
"Type": "metal",
"cust_1": "max"
}]
You can use the below function csvIntoJson to convert.
const csv = 'contry;fromNr;toNr;Type;cust_1;cust_2\nUS;0;100;wood;max;nuk\nDE;100;500;metal;max;pal';
const csvIntoJson = (csv, separator) => {
let [headers, ...rows] = csv.split('\n');
headers = headers.split(separator);
rows = rows.map(row => row.split(separator));
return rows.reduce((jsonArray, row) => {
const item = row.reduce((item, value, index) => {
return {...item, [headers[index]]: value};
}, {});
return jsonArray.concat(item);
}, []);
};
const jsonArray = csvIntoJson(csv, ';');
My suggestion use a library, But you still want to understand how it can be done then here is the simple code.
I have used ',' delimiter, You can change it to ';' or anything else as per your usecase.
steps:
Read csv as text
split text by new line to get rows
split row by delimiter like ',' or ';'
Do your stuff
code:
function Upload(input){
console.log("uploading");
let file = input.files[0];
let reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
map_object = [];
console.log(reader.result);
var textByLine = (reader.result).split("\n")
console.log(textByLine);
// read header
header = (textByLine[0]).split(',');
// read data
for(var i = 1 ; i< textByLine.length -1; i++){
temp_row = {}
row_data = textByLine[i].split(',');
for (var j = 0 ; j< header.length; j++){
temp_row[header[j]] = row_data[j]
}
console.log(temp_row);
map_object.push(temp_row);
}
console.log(map_object);
document.write(JSON.stringify(map_object));
};
reader.onerror = function() {
console.log(reader.error);
};
}
<input type="file" id="fileUpload" accept='.csv' onchange="Upload(this)"/>
var data = "contry;fromNr;toNr;Type;cust_1;cust_2\nUS;0;100;wood;max;nuk\nDE;100;500;metal;max;pal";
function CSVtoJSON(csv) {
var lines = csv.split("\n");
var result = [];
var headers = lines[0].split(";");
for (var i = 1; i < lines.length; i++) {
var obj = {};
var currentline = lines[i].split(";");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
return result;
}
console.log(CSVtoJSON(data));

Instantiate the value of an array from one function to a different function in jquery

I want to get the result of a jquery function attached to an id and change e.g
<script>
$('#dateID').change(function(){
var bookday = $(this).val();
$.post('getDates.php',{postbookday:bookday},
function(data){
var array = JSON.parse("[" + data + "]");
var list = [];
var newArray = array.flat([2]);
for (var i = 0; i < newArray.length; i++) {
list.push(newArray[i]);
};
if (list.length>96) {
alert("Sorry, day fully booked!");
}
else{
function selectedTime(list) {
return [a, b, c];
}
var result = selectedTime(list);
var myArray = [];
for (var i=0; i < result[2].length; i++) {
if (result[2][i] === '09:00') {
myArray.push(['09:00','10:00']);
}
if (result[2][i] === '10:00') {
myArray.push(['10:00','11:00']);
// here is myArray
}
}
}
});
});
</script>
and then use it as the input in another different function below:
$('#disableTimeRangesExample').timepicker(
{
'disableTimeRanges': myArray
}
);
How do I get myArray in the next function? considering that it is not static.
You have two options:
1. save the variable in outer scope:
var myArray;
$('#selectedDate').change(function(
...some computations...
myArray = [['1pm', '2pm']];
});
$('#disableTimeRangesExample').timepicker({
'disableTimeRanges': myArray
});
2. save in jQuery data
$('#selectedDate').change(function(
...some computations...
$(this).data('array', [['1pm', '2pm']]);
});
$('#disableTimeRangesExample').timepicker({
'disableTimeRanges': $('#selectedDate').data('array') || []
});
As a side note you will probably also need to update timepicker on each change.
EDIT: to update time picker on change of the input you need to put this inside change event:
$('#dateID').change(function(){
var bookday = $(this).val();
$.post('getDates.php',{postbookday:bookday},
function(data){
var array = JSON.parse("[" + data + "]");
var list = [];
var newArray = array.flat([2]);
for (var i = 0; i < newArray.length; i++) {
list.push(newArray[i]);
};
if (list.length>96) {
alert("Sorry, day fully booked!");
}
else{
function selectedTime(list) {
return [a, b, c];
}
var result = selectedTime(list);
var myArray = [];
for (var i=0; i < result[2].length; i++) {
if (result[2][i] === '09:00') {
myArray.push(['09:00','10:00']);
}
if (result[2][i] === '10:00') {
myArray.push(['10:00','11:00']);
// here is myArray
}
}
$('#disableTimeRangesExample').timepicker(
'option', {'disableTimeRanges': myArray}
);
}
});
});
$('#disableTimeRangesExample').timepicker();

Javascript Read data from spreadsheet

I am using a HTML form to get data from google spreadsheet.
I need to get the row where SerNo= 2 (or any specific number)
I am looping through the sheet and trying to get the values as below - but it does nothing
ex:
SerNo Col2
2 Option1
3 Option2
4 Option3
So,if SerNo=2 ...I want to get Option1.
This has 24 columns so i have used the getLastColumn
{function getDataRows_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
var lr= sh.getLastRow();
for(var i=1;i<=lr;i++){
var SerNo1 = sh.getRange(i, 2).getValue();
if(SerNo1==SerNo){
return sh.getRange(i, 2, 1, sh.getLastColumn()).getValues();
}
}
}
----edit---
I have posted the whole code I use since it looks like i am filtering records at the wrong place
function read_value(request,ss){
var output = ContentService.createTextOutput(),
data = {};
var sheet="sheet1";
data.records = readData_(ss, sheet);
var callback = request.parameters.callback;
if (callback === undefined) {
output.setContent(JSON.stringify(data));
} else {
output.setContent(callback + "(" + JSON.stringify(data) + ")");
}
output.setMimeType(ContentService.MimeType.JAVASCRIPT);
return output;
}
function readData_(ss, sheetname, properties) {
if (typeof properties == "undefined") {
properties = getHeaderRow_(ss, sheetname);
properties = properties.map(function(p) { return p.replace(/\s+/g, '_'); });
}
var rows = getDataRows_(ss, sheetname),
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
for (var p in properties) {
record[properties[p]] = row[p];
}
data.push(record);
}
return data;
}
function getDataRows_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(2, 1, sh.getLastRow() -1,sh.getLastColumn()).getValues();
}
function getHeaderRow_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(1, 1, 1, sh.getLastColumn()).getValues()[0];
}
One thing I would recommend is to not retrieve the data on row at a time; in other words retrieve all of the data that you want to search through into an array (i.e. row 1 through last row) and then test each row of the array, looking for your value.

Javascript: group JSON objects using specific key

I have the following JSON object and wanted to merge them by OrderID, making the items into array of objects:
[
{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
},
{
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}
]
and I'm wondering how in Javascript to merge the items on the same order...like this:
[{
"OrderID": "999123",
"Items": [{
"ItemCode": "DY-FBBO",
"ItemQuantity": "2",
"ItemName": "DOIY Foosball Bottle Opener > Red",
"ItemPrice": "34.95"
}, {
"ItemCode": "TED-072",
"ItemQuantity": "1",
"ItemName": "Ted Baker Womens Manicure Set",
"ItemPrice": "74.95"
}]
}]
I suggest you use javascript library like underscorejs/lazyjs/lodash to solve this kind of thing.
Here is the example on using underscorejs:
var data = [{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
}, {
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}]
var result = _.chain(data).groupBy(function (e) {
return e.OrderID;
}).map(function (val, key) {
return {
OrderID: key,
Items: _.map(val, function (eachItem) {
delete eachItem.OrderID;
return eachItem;
})
};
}).value();
Working example:
var data = [{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
}, {
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}];
var result = _.chain(data).groupBy(function (e) {
return e.OrderID;
}).map(function (val, key) {
return {
OrderID: key,
Items: _.map(val, function (eachItem) {
delete eachItem.OrderID;
return eachItem;
})
};
}).value();
document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
This should do what you want it to do, but it's rather a group function than a merge function :)
You can see the result in the browser console.
var items = [
{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
},
{
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}
];
function groupBy(ungrouped, groupByProperty) {
var result = [],
getGroup = function (arr, val, groupByProperty) {
var result, j, jlen;
for (j = 0, jlen = arr.length; j < jlen; j++) {
if (arr[j][groupByProperty] === val) {
result = arr[j];
break;
}
}
if (!result) {
result = {};
result.items = [];
result[groupByProperty] = val;
arr.push(result);
}
return result;
}, i, len, item;
for (i = 0, len = ungrouped.length; i < len; i++) {
item = getGroup(result, ungrouped[i][groupByProperty], groupByProperty);
delete ungrouped[i][groupByProperty];
item.items.push(ungrouped[i]);
}
return result;
}
var grouped = groupBy(items, 'OrderID');
document.getElementById('result').innerHTML = JSON.stringify(grouped);
console.log(grouped);
<div id="result"></div>
Lodash is a great Javascript Utility library that can help you in this case. Include the latest version of lodash in your code and group the objects like this:
var mergedOrders = _.groupBy(OriginalOrders, 'OrderID');
It seems you'll have to do a function that, for each entry, will check if it match
try this :
// your array is oldArr
var newArr = []
for (var i=0;i<oldArr.length;i++){
var found = false;
for(var j=0;j<newArr.length;j++){
if(oldArr[i]["OrderID"]==newArr[j]["OrderID"]){
newArr[j]["Items"].push(oldArr[i]);
found=true;
break;
}
if(!found){
newArr.push({"OrderID" : oldArr[i]["OrderID"], "Items" : oldArr[i]});
}
}
You need to loop and create new grouped objects according to your requirement.
For an easier approach I would suggest using jquery-linq
var qOrderIds = $.Enumerable.From(myArray).Select(function(item) { return item.OrderID; }).Distinct();
var groupedList = qOrderIds.Select(function(orderId) {
return {
OrderID: orderId,
Items : $.Enumerable.From(myArray).Where(function(item) { item.OrderID === orderId}).ToArray()
};
}).ToArray();
Thank you for all your answers.
I was able to attain my goal (maybe a bit dirty and not as beautiful as yours but it worked on my end). Hoping this might help others in the future:
function processJsonObj2(dataObj, cfg) {
var retVal = dataObj.reduce(function(x, y, i, array) {
if (x[cfg.colOrderId] === y[cfg.colOrderId]) {
var orderId = x[cfg.colOrderId];
var addressee = x[cfg.colAddressee];
var company = x[cfg.colCompany];
var addr1 = x[cfg.colAddress1];
var addr2 = x[cfg.colAddress2];
var suburb = x[cfg.colSuburb];
var state = x[cfg.colState];
var postcode = x[cfg.colPostcode];
var country = x[cfg.colCountry];
var orderMsg = x[cfg.colOrderMessage];
var carrier = x[cfg.colCarrier];
delete x[cfg.colOrderId];
delete y[cfg.colOrderId];
delete x[cfg.colAddressee];
delete y[cfg.colAddressee];
delete x[cfg.colCompany];
delete y[cfg.colCompany];
delete x[cfg.colAddress1];
delete y[cfg.colAddress1];
delete x[cfg.colAddress2];
delete y[cfg.colAddress2];
delete x[cfg.colSuburb];
delete y[cfg.colSuburb];
delete x[cfg.colState];
delete y[cfg.colState];
delete x[cfg.colPostcode];
delete y[cfg.colPostcode];
delete x[cfg.colCountry];
delete y[cfg.colCountry];
delete x[cfg.colOrderMessage];
delete y[cfg.colOrderMessage];
delete x[cfg.colCarrier];
delete y[cfg.colCarrier];
var orderObj = {};
orderObj[cfg.colOrderId] = orderId;
orderObj[cfg.colAddressee] = addressee;
orderObj[cfg.colCompany] = company;
orderObj[cfg.colAddress1] = addr1;
orderObj[cfg.colAddress2] = addr2;
orderObj[cfg.colSuburb] = suburb;
orderObj[cfg.colState] = state;
orderObj[cfg.colPostcode] = postcode;
orderObj[cfg.colCountry] = country;
orderObj[cfg.colOrderMessage] = orderMsg;
orderObj[cfg.colCarrier] = carrier;
orderObj["Items"] = [ x, y ];
return orderObj;
} else {
var orderId = x[cfg.colOrderId];
var addressee = x[cfg.colAddressee];
var company = x[cfg.colCompany];
var addr1 = x[cfg.colAddress1];
var addr2 = x[cfg.colAddress2];
var suburb = x[cfg.colSuburb];
var state = x[cfg.colState];
var postcode = x[cfg.colPostcode];
var country = x[cfg.colCountry];
var orderMsg = x[cfg.colOrderMessage];
var carrier = x[cfg.colCarrier];
var itemCode = x[cfg.colItemCode];
var itemQuantity = x[cfg.colItemQuantity];
var itemName = x[cfg.colItemName];
var itemPrice = x[cfg.colitemPrice];
var item = {};
item[cfg.colItemCode] = itemCode;
item[cfg.colItemQuantity] = itemQuantity;
item[cfg.colItemName] = itemName;
item[cfg.colItemPrice] = itemPrice;
var orderObj = {};
orderObj[cfg.colOrderId] = orderId;
orderObj[cfg.colAddressee] = addressee;
orderObj[cfg.colCompany] = company;
orderObj[cfg.colAddress1] = addr1;
orderObj[cfg.colAddress2] = addr2;
orderObj[cfg.colSuburb] = suburb;
orderObj[cfg.colState] = state;
orderObj[cfg.colPostcode] = postcode;
orderObj[cfg.colCountry] = country;
orderObj[cfg.colOrderMessage] = orderMsg;
orderObj[cfg.colCarrier] = carrier;
orderObj["Items"] = [ item ];
return orderObj;
}
});
return retVal;
}

change the json structure after getting data

I am getting a json data having structure
{
SearchDAO: [
{
PERSONADDRESS_H_ADDRESS_LINE_ONE: "599 Waterloo place",
PERSON_H_BIRTHDATE_VALUE: "1939-01-11 00:00:00",
PERSON_H_CREATE_TS: "2012-11-22 11:17:13.879",
PERSON_H_GENDER_CD: "M"
}
]
}
As you can see in the data set two type of keys are there
1. starting with "PERSONADDRESS"
2. starting with "PERSON"
I have to convert this structure to
{
"PERSON":[
{
H_BIRTHDATE_VALUE: "1939-01-11 00:00:00",
H_CREATE_TS: "2012-11-22 11:17:13.879",
H_GENDER_CD: "M"
}
],
"PERSONADDRESS":[
{
H_ADDRESS_LINE_ONE: "599 Waterloo place"
}
]
I am struggling to do this.
As It need to splice key string and change the structure
Please help
I am trying something like this
$.each(data.SearchDAO[0], function(k, v) {
var streetaddress= k.substr(0, k.indexOf('_'));
console.log(streetaddress)
if(returnVar[streetaddress] == undefined){
thisItem = [];
returnVar[streetaddress] = thisItem;
}
else {
thisItem = returnVar[streetaddress];
}
var obj = {};
obj.issueValue = v;
thisItem.push(obj);
});
console.log(thisItem)
I solved the problem
here is my code
returnVar={};
$.each(data.SearchDAO[0], function(k, v) {
var streetaddress= k.substr(0, k.indexOf('_'));
var keyFinal= k.substr(k.indexOf('_')+1,k.length-1);
console.log(keyFinal)
if(returnVar[streetaddress] == undefined){
thisItem = {};
returnVar[streetaddress] = thisItem;
thisItem[keyFinal]=v;
}
else {
thisItem = returnVar[streetaddress];
thisItem[keyFinal]=v;
}
});
console.log(returnVar)
This should do it (for multiple persons as well):
var json = {
SearchDAO: [
{
PERSONADDRESS_H_ADDRESS_LINE_ONE: "599 Waterloo place",
PERSON_H_BIRTHDATE_VALUE: "1939-01-11 00:00:00",
PERSON_H_CREATE_TS: "2012-11-22 11:17:13.879",
PERSON_H_GENDER_CD: "M"
},
{
PERSONADDRESS_H_ADDRESS_LINE_ONE: "123 Place",
PERSON_H_BIRTHDATE_VALUE: "1901-01-01 00:00:00",
PERSON_H_CREATE_TS: "2001-01-01 00:00:00.000",
PERSON_H_GENDER_CD: "F"
}
]
}
var converted = {};
for (var i = 0; i < json.SearchDAO.length; i++)
{
var row = json.SearchDAO[i];
var keys = Object.keys(row);
for (var j = 0; j < keys.length; j++)
{
var key = keys[j];
var key_prefix = key.substr(0, key.indexOf('_'));
var key_suffix = key.substr(key.indexOf('_') + 1);
if (!(key_prefix in converted)) converted[key_prefix] = [];
if (!(i in converted[key_prefix])) converted[key_prefix][i] = {};
converted[key_prefix][i][key_suffix] = row[key_prefix + "_" + key_suffix];
}
}

Categories