How can I Group Rows via the Google Sheets API? - google-sheets-api

I'm looking for a way to create a group of rows via the Google Sheets API - is there a way to do this? I can't see to find an API that will do this, but it seems like it should be a fairly common formatting need.
This feature is supported in the UI by selecting a set of rows, right clicking and the option pops up to create a group, see the screenshot linked below. I'm just looking for a way to do that via an API.

Use this --> Range.shiftColumnGroupDepth
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var range = sheet.getActiveRange();
// The column grouping depth is increased by 1.
range.shiftColumnGroupDepth(1);
// The column grouping depth is decreased by 1.
range.shiftColumnGroupDepth(-1);

You can accomplish this through version 4 of the Google Sheets API.
You will need to submit an HTTP POST to this endpoint:
https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate
You will need to pass a valid JSON request. I created a simple spreadsheet with some rows to group and used this JSON as a test to group rows 14-17:
{
"requests": [
{
"addDimensionGroup": {
"range": {
"dimension": "ROWS",
"sheetId": 0,
"startIndex": 14,
"endIndex": 17
}
}
}
]
}
Note that the startIndex is the row (or column) number that everything will fold into and will remain visible even if you collapse the group, while endIndex is the last element of the group which will remain hidden when the group is collapsed.
The documentation for this is here. If your window is wide enough it will show a "Try this API" pane on the right side. You can enter the spreadsheetId of your sheet and build up the JSON request body and test it to see it work directly on a sheet - if you have it open in another window you should see the update happen almost immediate after you click the "Execute" button.

Creating Column and Row Groups
Column Groups
function createSomeColumGroups() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName("Sheet189");//this is used in the request
var resource='{"requests": [';
for(var i=1;i<25;i+=3) {//start at column 1 and ends at 24 making them in groups of 3
if(i>1){resource+=', ';}
resource+=Utilities.formatString('{"addDimensionGroup": {"range": {"dimension": "COLUMNS","sheetId": %s,"startIndex": %s ,"endIndex": %s}}}',sh.getSheetId(),i,i+2);
}
resource+=']}';
Logger.log(resource);
Sheets.Spreadsheets.batchUpdate(resource, ss.getId());
}
Row Groups
function createSomeRowGroups() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName("Sheet189");
var resource='{"requests": [';
for(var i=1;i<25;i+=3) {
if(i>1){resource+=', ';}
resource+=Utilities.formatString('{"addDimensionGroup": {"range": {"dimension": "ROWS","sheetId": %s,"startIndex": %s ,"endIndex": %s}}}',sh.getSheetId(),i,i+2);
}
resource+=']}';
Logger.log(resource);
Sheets.Spreadsheets.batchUpdate(resource, ss.getId());
}
Don't forget to go the Advanced Google Services and enable Sheets API version 4 and you will also have to enable on the Google Cloud Platform

Related

JQuery Datatables SearchPane Filter Value

I am using the SearchPanes extension to Datatables, I am trying to capture the value of the item in the SearchPane they chose, it appears that since SearchPanes uses filter() instead of search() that value is not available. Am I wrong?
You can access the selections as follows:
1) Add stateSave: true to the DataTable initialization definition. See this example.
This will cause all selections to be saved in the browser's local storage.
2) Use the following logic to access the browser's local storage:
var myStorage = window.localStorage;
var searchPanes = JSON.parse(myStorage.getItem('yourStorageIndexGoesHere'));
//console.log(searchPanes); // the full JSON - large!
//console.log(searchPanes['searchPanes']['panes']); // one object per search pane
searchPanes['searchPanes']['panes'].forEach(function(pane) {
console.log('ID = ' + pane.id + ' - selected: ' + pane.selected);
});
In my case, I used the search panes shown in this demo.
Here is a screenshot with some selections:
Here is what the sample code writes to the browser console for the above selections:
The "ID" data value is a zero-based column index. So, column 3 (index 2) is the Office column, and column 6 (index 5) is the Salary column.
The related "selected" data are arrays, containing one or more value. You can iterate the arrays to get each separate value.
You will need to replace yourStorageIndexGoesHere with the actual name of your storage entry. The easiest (manual) way to find this is to perform a filter using SearchPanes, and then open your browser tools (usually F12). Then (assuming FireFox in my case) navigate to Storage > Local Storage > and select the relevant key text.
Points to Note:
a) This assumes you are OK with activating the "local storage" feature. It means that the browser will remember the last applied filter, and re-apply it when a user returns to the DataTable browser page. If users do not want that feature, then my solution will not be suitable for you.
b) I can't advise you on where you need to place the JavaScript I provided, because I don't know what you want to do with this information. But, for example, you might want to use it after every draw() event - in which case, see here.
Jsut want to add, how the search pattern or the preselected searchPanes filters can be erased on demand - is stateSave is been enabled.
.on( 'stateLoadParams.dt', function (e, settings, data) {
//get the last search pattern, if this setting is enabled
//if not, erase last search
if (!cnf_lastSearch) {
//erase search input field
data.search.search = '';
data.start = 0;
//console.log(data)
} else {
}
//search through search panes array and erase content
if (!cnf_searchPanes) {
$.each((data['searchPanes']['panes']), function( i, val ) {
val.selected = '';
});
}
})

How can I override the total sum of the EXTJS summary?

I am using EXTJS 4.2.1 and my application has a grid including paging, the grouping summary and the summary feature. I want to override the sum of the summary feature, because it should display the grand total sum of the whole data set and not only for the current displayed page.
Is that possible to override the summary feature to do so?
Thanky you very much for every advice in advance. :-)
Use summaryRenderer in column configuration. It is an undocummented feature of ExtJS allowing you to show custom data in your summary row.
You will have to summarize the data server-side and send them to client where you will access it in the summaryRenderer.
Like so:
columns: {
items: [
{
text: "Column A",
dataIndex: "field_A",
summaryRenderer: function( value, summaryData, dataIndex ) {
var grid = this;
// Get the value here and return it
var result = functionToGetValue( grid );
return result;
}
},
// ...
}
]
The functionToGetValue is the place where you pass the summarization value you sent to your client from server.
How you do that depens on your code. You have access to store via grid.getStore().
It is possible to add the summary data to each record and then simply use store.getAt(0).get( 'summaryValue' ), it is kind of wasteful, but it is simple and it works.

jQuery DataTable filtering - so confusing

I am new to the jQuery dataTables plugin found on https://datatables.net/
I am trying to implement a custom filter for the table:
Basically, when I click a button, a custom filtering function will test the value of column #1 (numeric value) for all rows, and if the value in the column < 50 for a row, the row stays, otherwise the row is hidden.
The concept should be very simple, but I can't seem to find the right way to use the API:
column.filter() returns an array of column value
column.search() can only accept text data (not function)
What's the API that can achieve the effect?
Is there anything like the following?
var api = $('#table').DataTable();
api.column(1).data().somefilterfunction(function (val, ind) {
return parseFloat(val) < 50;
}).draw();
Have you seen this article in the documentation -> https://datatables.net/examples/plug-ins/range_filtering.html ??
You can create a custom filtering function on-the-fly, triggered by a button :
<button id="filter">filter < 50</button>
script :
$("#filter").click(function() {
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
return parseFloat(data[0])<50
? true
: false
}
);
table.draw();
$.fn.dataTable.ext.search.pop();
});
demo -> http://jsfiddle.net/dpwgqs2o/
Notice that the filter is created inside the click handler itself, and removed again as soon the table is drawn. This makes the filter temporary, i.e when the user click on a column header, the filter is cleared. If you want a permanent filter, make the filter global and do not remove it.

Getting id from row clicked on a dgrid List

I just started using dgrid, and going through the dTunes sample, I'm unable to find the id associated with each row in the list. This is pretty remedial on my part, but how would I also get the id I sent from the datasource?
define([
'require',
'dgrid/List',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dgrid/Keyboard',
'dgrid/extensions/ColumnHider',
'dojo/_base/declare',
'dojo/_base/array',
'dojo/Stateful',
'dojo/when',
'dstore/RequestMemory',
'put-selector/put',
'dojo/domReady!'
], function (require, List, Grid, Selection,
Keyboard, Hider, declare, arrayUtil, Stateful,
when, RequestMemory, put) {
var cstsNode = put(listNode, 'div#cstsCars');
...
var cstsList = new TunesList({}, cstsNode);
var dataCSTS = new RequestMemory({ target: require.toUrl('./dataCSTS.json') });
...
dataCSTS.fetch().then(function (cars) {
cstsCars = arrayUtil.map(cars, pickField('Description'));
cstsCars.unshift('All (' + cstsCars.length + ' CSTS Cars' + (cstsCars.length !== 1 ? 's' : '') + ')');
cstsList.renderArray(cstsCars);
});
...
cstsList.on('dgrid-select', function (event) {
var row = event.rows[0];
console.log(row.id); // shows row number. How do I get the real id or other fields?
console.log(row.data); // shows row text that is displayed ("sample text 1")
console.log(row.data.id); // undefined
});
Here is a snippet of sample data like I'm supplying:
[{"id":"221","Description":"sample text 1"},
{"id":"222","Description":"sample text 2"},
{"id":"223","Description":"sample text 3"}]
I'd like to see the id. Instead, row.id returns 1,2 and 3, ie the row numbers (or id dgrid created?).
You haven't really shown a complete example, but given that you're using a store anyway, you'd have a much easier time if you let dgrid manage querying the store for you. If you use dgrid/OnDemandList (or dgrid/List plus dgrid/extensions/Pagination), you can pass your dataCSTS store to the collection property, it will render it all for you, and it will properly pick up your IDs (since Memory, and RequestMemory by extension, default to using id as their identity property).
The most appropriate place to do what you're currently doing prior to renderArray would probably be in the renderRow method if you're just using List, not Grid. (The default in List just returns a div with a text node containing whatever is passed to it; you'll be passing an object, so you'd want to dig out whatever property you actually want to display, first.)
If you want a header row, consider setting showHeader: true and implementing renderHeader. (This is false in List by default, but Grid sets it to true and implements it.)
You might want to check out the Grids and Stores tutorial.
I think the problem might be that I was modeling my code based on the dTunes sample code, which has 3 lists that behave a little differently than a regular grid.
For now, I'm using the cachingStore that is available in the lists. So the way I get the id:
cstsList.on('dgrid-select', function (event) {
var row = event.rows[0];
var id = storeCSTS.cachingStore.data[row.id - 1].id; // -1 because a header was added
console.log(id);
});
I'm not sure whether this will work if I ever try to do sorting.

Retrieve the traffic variable in RankedReport of Adobe Sitecatalyst

Is it possible to fetch a traffic variable sProp1 along with PageName and Url when issuing a GetReport request of a Ranked report?
Let us say I have the following passed to SiteCatalyst (Omniture) via Java Script.
s.pageName = o_title; // Page Name
s.channel = o_structure; // SiteSection
s.prop1 = o_inode // Traffic variable also the Primary Key Id of the PageName
Now, if I run a RankedReport, I will get the following
PageName
PageViews
Url
Along with this info, I will also be interested in fetching the s.prop1 value. I will need the s.prop1 value to use it on my db to query the first sentence of the article from db (and other metadata) and show the results on the results page that shows the most popular pages. Can this be achieved? I mean is it possible to get the traffic variable associated with the pageName?
Thanks,
Rag
OK. I think I if I add another element (prop1) I get the breakdown. {
"reportDescription":{
"reportSuiteID":"*",
"dateFrom":"2013-03-06",
"dateTo":"2013-03-15",
"metrics":[
{
"id":"pageviews",
"name":"Page Views",
"type":"number"
}
],
"sortBy":"pageviews",
"elements":[
{
"id":"siteSection"
},
{
"id":"page"
},
{
"id":"prop1"
}
],
"locale":"en_US"
},
"validate":"false"
}