JqxWidgets: Export nested grid - grid

While working with JqxWidges I met a problem with exporting nested grids which use one JSON as a source file. The common solution doesn't work. Actually it exports only parent grid colums.
$("#excelExport").click(function () {
$("#jqxGrid").jqxGrid('exportdata', 'csv', chartName + ' ' + date);
});
One of the existing solutions (http://www.jqwidgets.com/community/reply/reply-to-export-data-from-a-nested-grid-13/) propose to push nested rows into data array while calling initrowdetails function.
Yes it works! But only for nested grids and in case when this grid was selected.

So, from this step I am moving to next aproach:
To collect all necessary data into array using initial JSON (prevent you from gathering only separate selected data);
To initialise parent grid columns with all existing data and mark nested columns as hidden. Then when export don't forget to add true parameter to export both non/hidden columns;
Use standard export with custom array parameter;
That's it!
Data collecting:
var toExport = data.allClientsCountChart;
var exp = new Array();
for(var i in toExport){
var client = {};
var countr = toExport[i].countries;
client[labels.clientType]=toExport[i].clientType;
client[labels.clientTypeCount]=toExport[i].clientTypeCount;
exp.push(client);
for(var j in countr) {
var country = {}
var detailes = countr[j].clientDetails;
country[labels.countryType]=countr[j].countryType;
country[labels.clientsNumber]=countr[j].clientsNumber;
exp.push(country);
for(var d in detailes) {
var det = {}
det[labels.scriptName]=detailes[d].scriptName;
det[labels.clientsCount]=detailes[d].clientsCount;
exp.push(det);
}
}
}
Export:
$("#excelExport").click(function () {
$("#jqxGrid").jqxGrid('exportdata', 'csv', chartName + ' ' + date, true, exp, true);
}
And don't forget to set the fifth pafameter into true to export hidden columns.
No doubds, it looks hardcoded. But it works for me.
So, if you have a good solution - please leave a comment!!!

Related

How to separate multiple columns from a range in an array?

I have a range of data in a Google Sheet and I want to store that data into an array using the app script. At the moment I can bring in the data easily enough and put it into an array with this code:
var sheetData = sheet.getSheetByName('Fruit').getRange('A1:C2').getValues()
However, this puts each row into an array. For example, [[Apple,Red,Round],[Banana,Yellow,Long]].
How can I arrange the array by columns so it would look: [[Apple,Banana],[Red,Yellow],[Round,Long]].
Thanks.
It looks like you have to transpose the array. You can create a function
function transpose(data) {
return (data[0] || []).map (function (col , colIndex) {
return data.map (function (row) {
return row[colIndex];
});
});
}
and then pass the values obtained by .getValues() to that function..
var sheetData = transpose(sheet.getSheetByName('Fruit').getRange('A1:C2').getValues())
and check the log. See if that works for you?
Use the Google Sheets API, which allows you to specify the primary dimension of the response. To do so, first you must enable the API and the advanced service
To acquire values most efficiently, use the spreadsheets.values endpoints, either get or batchGet as appropriate. You are able to supply optional arguments to both calls, and one of which controls the orientation of the response:
const wb = SpreadsheetApp.getActive();
const valService = Sheets.Spreadsheets.Values;
const asColumn2D = { majorDimension: SpreadsheetApp.Dimension.COLUMNS };
const asRow2D = { majorDimension: SpreadsheetApp.Dimension.ROWS }; // this is the default
var sheet = wb.getSheetByName("some name");
var rgPrefix = "'" + sheet.getName() + "'!";
// spreadsheetId, range string, {optional arguments}
var single = valService.get(wb.getId(), rgPrefix + "A1:C30");
var singleAsCols = valService.get(wb.getId(), rgPrefix + "A1:C30", asColumn2D);
// spreadsheetId, {other arguments}
var batchAsCols = valService.batchGet(wb.getId(), {
ranges: [
rgPrefix + "A1:C30",
rgPrefix + "J8",
...
],
majorDimension: SpreadsheetApp.Dimension.COLUMNS
});
console.log({rowResp: single, colResp: singleAsCols, batchResponse: batchAsCols});
The reply will either be a ValueRange (using get) or an object wrapping several ValueRanges (if using batchGet). You can access the data (if any was present) at the ValueRange's values property. Note that trailing blanks are omitted.
You can find more information in the Sheets API documentation, and other relevant Stack Overflow questions such as this one.

Performance server scripting

I have table with multiple customerKey values assigned to a numeric value; I wrote a script where foreach row of data I scan whole table to find all values assigned to the current customerKey and return a highest one;
I have a problem with performance - script processes around 10 records per second - any ideas how to improve this or maybe propose an alternative solution plesae?
function getLastest() {
var date = app.models.magicMain.newQuery();
var date_all = date.run();
date_all.forEach(function(e) { // for every row of date_all
var temp = date_all.filter(function(x) {
return x.SubscriberKey === e.SubscriberKey; // find matching records for the current x.SubscriberKey
});
var dates = [];
temp.forEach(function(z) { // get all matching "dates"
dates.push(z.Date);
});
var finalValue = dates.reduce(function(a, b) { // get highest dates value (integer)
return Math.max(a, b);
});
var record = app.models.TempOperatoins.newRecord(); // save results to DB
record.email = e.SubscriberKey.toString() + " " + finalValue.toString();
app.saveRecords([record]);
});
}
The only suggestion I have would be to add:
var recordstosave = [];
At the top of your function.
Then replace app.saveRecords([record]) with recordstosave.push(record).
Finally outside of your foreach function do app.saveRecords(recordstosave).
I saw major processing time improvements doing this rather than saving each record individually inside a loop.

Crossfilter: how to build custom reduce functions when I want to access a specific array-value?

I have constructed my crossfilter-setup a bit different than in most examples I can find, namely:
I have data-array d with multiple data-sources included, among which is data1.
var cf = crossfilter(d3.range(0, d.data1.length));
Then I construct my dims like:
var dim = cf.dimension(function(i) { return d.data1[i].id; });
And I construct my groups like:
var group = dim.group().reduceSum(function(i) { return d.data1[i].total;});
This all works fine, but when I want to create custom reduce functions, the extra parameter i is giving me trouble.
var reduceAddPerc = function(p,v) {
p.sumOfSub += d.data1[i].var1;
p.sumOfTotal += d.data1[i].total;
p.finalVal = p.sumOfSub / p.sumOfTotal;
return p;
};
var reduceRemovePerc = function(p,v) {
p.sumOfSub -= d.data1[i].var1;
p.sumOfTotal -= d.data1[i].total;
p.finalVal = p.sumOfSub / p.sumOfTotal;
return p;
};
var reduceInitialPerc = function() {
return {sumOfSub:0, sumOfTotal:0, finalVal:0 };
};
And then defining the group with:
var group = dim.group().reduce(reduceAddPerc,reduceRemovePerc,reduceInitialPerc);
This doesn't work obviously, since the parameter i is now not known within the function. But I've tried adding the parameter (p,v,i), or nesting the functions by creating an additional function with parameter i around the (p,v) function, and also creating an additionao function(i) within the (p,v) function, but I cannot get this to work.
Does anyone have any help to offer?
In the custom reduce functions, the v parameter is the record currently being "reduced". In this case, it should be your counter, so just use it where you would normally use i. Is that not working?

update edited cells within treetable after expand/collapse items

I have a treeTable with editable cells within the expanded rows. The editable cells get a dirty flag after editing (in the example the background color is set to red).
The problem i'm running into is that i found no certain way to update the dirty flag on expand/collapse (edited cells get the css class 'edited-cell').
At the moment the code looks like that:
// each editable textfield gets a Listener
textField.attachLiveChange(
var source = oEvent.oSource;
...
jQuery('#' + source.getId()).addClass(EDITED_CELL_CLASS, false)
// list with cell ids, e.g. "__field1-col1-row1"
DIRTY_MODELS.push(model.getId()) //*** add also binding context of row
)
// the table rows are updated on toggleOpenState
new sap.ui.table.TreeTable({
toggleOpenState: function(oEvent) {
...
this.updateRows() // see function below
}
})
// update Rows function is also delegated
oTable.addDelegate({ onAfterRendering : jQuery.proxy(this.updateRows, oTable)});
//http://stackoverflow.com/questions/23683627/access-row-for-styling-in-sap-ui5-template-handler-using-jquery
// this method is called on each expand/collapse: here i can make sure that the whole row has it's correct styling...
// but how to make sure that special cells are dirty?
function updateRows(oEvent) {
if (oEvent.type !== 'AfterRendering'){
this.onvscroll(oEvent);
}
var rows = this.getVisibleRowCount();
var rowStart = this.getFirstVisibleRow();
var actualRow;
for (var i = 0; i < rows; i++){
actualRow = this.getContextByIndex(rowStart + i); //content
var row = this.getRows()[i]
var obj = actualRow.getObject()
var rowId = row.getId()
updateStyleOfRows(obj, rowId, actualRow)
updateDirtyCells(rowId) //*** how to get the binding context in this function???
}
};
// update Dirty Cells in function updateRows():
function updateDirtyCells(rowId){
for (var i = 0; i < DIRTY_MODELS.length; i++){
var dirtyCellId = DIRTY_MODELS[i]
//*** make sure that only the correct expanded/collapsed rows will be updated -> depends on the bindingContext of the row
jQuery('#' + rowId).find('#' + dirtyCellId + '.editable-cell').addClass(EDITED_CELL_CLASS, false)
}
}
This doesn't work correctly, because the ids of the cells change on each layout render (e.g. collapse/expand rows). Please see attached image.
Let me know if i should provide more information.

How to pre-select an option in a dropdown knockout js

I've looked at this other question, but can't get my select box to work correctly:
Binding initial/default value of dropdown (select) list
I've got the following Game object:
function Game(visitingTeamDetails, homeTeamDetails, game) {
if (arguments.length > 0) {
this.VisitingTeamDetails = visitingTeamDetails;
this.HomeTeamDetails = homeTeamDetails;
this.GameId = ko.observable(game.GameId);
this.HomeTeamName = ko.observable(game.HomeTeamName);
this.VisitingTeamName = ko.observable(game.VisitingTeamName);
this.SportTypeName = ko.observable(game.SportTypeName);
this.HomeAccountName = ko.observable(game.HomeAccountName);
this.VisitingAccountName = ko.observable(game.VisitingAccountName);
this.GameDateString = ko.observable(game.GameDateString);
this.GameTimeString = ko.observable(game.GameTimeString);
this.AvailableSportTypes = ko.observableArray(game.Sports);
this.sportTypeFunction = function () {
for (sportType in this.AvailableSportTypes()) {
if (this.AvailableSportTypes()[sportType].Name == this.SportTypeName()) {
return this.AvailableSportTypes()[sportType];
}
}
return null;
};
this.SportType = ko.observable(game.SportType);
}
}
SportType is an object with Name and SportTypeId.
I have the following template:
<td rowspan="3"><select data-bind="options: AvailableSportTypes, value: SportType, optionsText:'Name', optionsCaption: 'Choose...'" class="sportType"></select></td>
AvailableSportTypes is a list of SportType.
The list is coming in with the names of the SportTypes in the drop down list, but I can't make the initial selection be SportType. I wrote sportTypeFunction to show myself that the data was coming in correctly, and it would select the correct value, but changing my selection in the drop down would not update SportType.
I'm sure I'm doing something wrong. Anyone see it?
Thanks
When game.SportType gets passed in, it needs to be a reference to the an item in the game.AvailableSportTypes and not just an object that looks the same.
Basically two objects are not equal unless they are actually a reference to the same object.
var a = { name: "test" },
b = { name: "test" };
alert(a === b); //false
So, you would need to call your function to locate the correct object in the array and set it as the value of your observable.
Not that it is way better, but in KO 1.3 you can extend .fn of observables, observableArrays, and dependentObservables to add additional functionality.
Here is a sample: http://jsfiddle.net/rniemeyer/ZP79w

Resources