I have a single select parameter that I define in a data studio community connector in getConfig() as below. The parameter is then used as a dropdown data control in the report.
config
.newSelectSingle()
.setId("characteristic_selected")
.setName("Characteristic selected")
.addOption(
config
.newOptionBuilder()
.setLabel("a")
.setValue("a")
)
.addOption(
config
.newOptionBuilder()
.setLabel("b")
.setValue("b")
)
.addOption(
config
.newOptionBuilder()
.setLabel("c")
.setValue("c")
)
.addOption(
config
.newOptionBuilder()
.setLabel("d")
.setValue("d")
)
.addOption(
config
.newOptionBuilder()
.setLabel("e")
.setValue("e")
)
.setAllowOverride(true);
In getFields() I define Characteristic which then returns data from the database a, b, c, d or e:
fields.newDimension()
.setId('Characteristic')
.setType(types.TEXT);
I am trying to define a calculated field which I will then use as a filter in my charts and tables to only display data for the option selected by the user in the dropdown data control. E.g. if the user selects "b", then only data labelled "b" for Characteristic will display.
My attempt (inspired by the answer here: How to use a Parameter in calculated field defined in getFields() (Google Data Studio Community Connector)?) is:
fields.newDimension()
.setId('Characteristic calc')
.setDescription('Sets true if characteristic selected in dropdown is the same as the characteristic dimension field')
.setFormula('$Characteristic = "' + request.configParams.characteristic_selected + '"')
.setType(types.BOOLEAN);
I then apply a filter to the tables and charts only include Characteristic calc = True
The default is "a". When I first load the page, the data filters correctly and only displays "a". However when I select "b" from the dropdown data control, it still only displays data for "a". It appears that the code does not capture the updated configParam when changed in the report.
Note: if I set the calculated field up in the report as opposed to in the data studio connector, then it works correctly. I use the connector in lots of reports however, so it is annoying to have to create the calculated field each time I create a new report.
Sorry, using the .setFormula will only work, if the parameter is only set during the source configuration. If the user can change it in the report the field calculation has to be done in the function getSchema(request).
function getSchema(request) {
var fields = cc.getFields();
var types = cc.FieldType;
fields.newDimension()
.setId('Characteristic_info_info')
.setDescription('tempory field')
.setType(types.TEXT);
fields.newDimension()
.setId('Characteristic calc')
.setDescription('Sets true if characteristic selected in dropdown is the same as the characteristic dimension field')
.setFormula('$Characteristic = $Characteristic_info_info')
.setType(types.BOOLEAN);
Then set the column to the right value in this function:
function getData(request) {
....
var schemaE = getFields(request).forIds(
request.fields.map(function(field) {
return field.name;
})
).build();
var out1=[];
schemaE.forEach(a=>out1.push(a.name in params ? params[a.name] : 'nope:'+a.name ));
var out= {
schema: schemaE,
rows: [{values:out1},{values:out1},{values:out1}]
};
console.log(schemaE)
console.log(request.configParams.characteristic_selected)
for(let col in schemaE){
if(schemaE[col].name=="Characteristic_info_info"){
for(let i in out.rows)
{
out.rows[i].values[col]=request.configParams.characteristic_selected+"!";
}
}
}
return out;
}
If a paramter could be used in .setFormula and not only $ for fields, life would be much easier.
The situation:
I am trying to load a dataset and then add additional criteria (filters) to the dataset based off users selected fields. The whole dev is a "Custom Report" build using a suitlete that has some fields the user can populate to choose "dynamic filters". When they click on the generate button I add the criteria/filters to a search and dataset and then join the results and display them.
The issue is that while I am able to add filters to the search after I load it no matter what I try I can't seem to add filters to the Dataset.
This code gets the dataset Data:
var datasetData = datasetLib.load({ id: datasetId });
resultSet.pageRanges.forEach(function (pageRange) {
// Fetch the results on the current page
var myPage = resultSet.fetch({ index: pageRange.index });
res.data = res.data.concat(myPage.data.results);
if (res.columns.length < 1) {
var columns = JSON.parse(myPage.pagedData.queryDefinition).columns;
for (var i = 0; i < columns.length; i++) {
res.columns.push(columns[i].label);
}
}
});
I attempted many different iterations to create the condition... here is one:
dataset.createCondition({
column: datasetData.columns[0], // I loaded the dataset and use it to reference the column
operator: query.Operator.ANY_OF,
values: params.customer.split(',')
})
Now the above code DOSE create a condition but when I attempt to add it into the dataset's current conditions I receive errors.I am attempting to push it into the child parameter of the parent criteria.
Please ask if you need more info...
If using a workbook is fine then I would suggest you to load the workbook using your above dataset using the query module and then use the above createCondition to add the condition to the loaded query dynamically.
var myLoadedQuery = query.load({
id: 'custworkbook237'
});
var mySalesRepJoin = myLoadedQuery.autoJoin({
fieldId: 'salesrep'
});
var thirdCondition = mySalesRepJoin.createCondition({
fieldId: 'email,
operator: query.Operator.START_WITH_NOT,
values: 'foo'
});
I would also urge to ensure the joins are accurately represented by looking at the Records catalog via Setup>Records Catalog. Hope this helps.
I know that checkbox is a relatively new feature in Google Sheets, so I'm trying to find a way to automatically create checkboxes in cells.
So far, I haven't found a reference regarding this in Google Apps Script documentation.
Currently I'm doing it manually, but any suggestion using script will be much appreciated.
UPDATE(April 2019)
You can now directly insertCheckboxes(or removeCheckboxes) on a Range or RangeList without any workarounds. You can also change the checked value/unchecked value using alternate method signatures found in the documentation.
Snippet:
SpreadsheetApp.getActive()
.getRange('Sheet2!A2:A10')
.insertCheckboxes();
I'm not sure when they did it, but they've added this now.
Use class DataValidationBuilder's requireCheckbox() method. Example:
function setCheckboxes() {
// Assumes there's only one sheet
var sheet = SpreadsheetApp.getActiveSheet();
// This represents ALL the data
var dataRange = sheet.getDataRange();
/* Get checkbox range from sheet data range. Assumes checkboxes are on the
left-most column
*/
var dataRangeRow = dataRange.getRow();
var dataRangeColumn = dataRange.getColumn();
var dataRangeLastRow = dataRange.getLastRow();
var checkboxRange = sheet.getRange(
dataRangeRow,
dataRangeColumn,
dataRangeLastRow
);
var enforceCheckbox = SpreadsheetApp.newDataValidation();
enforceCheckbox.requireCheckbox();
enforceCheckbox.setAllowInvalid(false);
enforceCheckbox.build();
checkboxRange.setDataValidation(enforceCheckbox);
}
You want to create the checkbox in the cells of spreadsheet using the scripts. If my understanding is correct, how about this workaround? Unfortunately, the Class SpreadsheetApp has no methods for creating the checkbox yet. (When such methods are tried to be used, the error occurs.) So I would like to propose to create it using Sheets API.
When I saw ConditionType of dataValidation, the document of BOOLEAN says
The cell's value must be TRUE/FALSE or in the list of condition values. Supported by data validation. Renders as a cell checkbox. ...
From this, I could understand how to create the checkbox using Sheets API. The following script is a sample script. This creates 6 checkboxes to "A1:C3". When you use this script, please enable Sheets API at Advanced Google Services and API console as follows.
Enable Sheets API v4 at Advanced Google Services
On script editor
Resources -> Advanced Google Services
Turn on Google Sheets API v4
Enable Sheets API v4 at API console
On script editor
Resources -> Cloud Platform project
View API console
At Getting started, click Enable APIs and get credentials like keys.
At left side, click Library.
At Search for APIs & services, input "sheets". And click Google Sheets API.
Click Enable button.
If API has already been enabled, please don't turn off.
If now you are opening the script editor with the script for using Sheets API, you can enable Sheets API for the project by accessing this URL https://console.cloud.google.com/apis/library/sheets.googleapis.com/
Sample script :
In this sample script, the checkboxes are created to "A1:C3" of Sheet1. Please use this script as the container-bound script.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetId = ss.getSheetByName("Sheet1").getSheetId();
var resource = {"requests": [
{
"repeatCell": {
"cell": {"dataValidation": {"condition": {"type": "BOOLEAN"}}},
"range": {"sheetId": sheetId, "startRowIndex": 0, "endRowIndex": 3, "startColumnIndex": 0, "endColumnIndex": 3},
"fields": "dataValidation"
}
},
{
"updateCells": {
"rows": [
{"values": [{"userEnteredValue": {"boolValue": true}}, {"userEnteredValue": {"boolValue": false}}, {"userEnteredValue": {"boolValue": false}}]},
{"values": [{"userEnteredValue": {"boolValue": true}}, {"userEnteredValue": {"boolValue": true}}, {"userEnteredValue": {"boolValue": false}}]},
{"values": [{"userEnteredValue": {"boolValue": true}}, {"userEnteredValue": {"boolValue": true}}, {"userEnteredValue": {"boolValue": true}}]}
],
"start": {"rowIndex": 0, "columnIndex": 0, "sheetId": sheetId},
"fields": "userEnteredValue"
}
}
]};
Sheets.Spreadsheets.batchUpdate(resource, ss.getId());
Flow :
dataValidation is set using repeatCell.
boolValue is set using updateCells.
Result :
Note :
This is a simple sample script. So please modify this for your environment.
When the methods of the Class SpreadsheetApp for creating the checkbox can be used, I think that the following sample script might be able to be used.
Script for Class SpreadsheetApp
At June 22, 2018, this script returns an error of the server error yet.
var rule = SpreadsheetApp.newDataValidation().withCriteria(SpreadsheetApp.DataValidationCriteria.CHECKBOX, ["TRUE", "FALSE"]).build();
SpreadsheetApp.getActiveSheet().getRange("A1").setDataValidation(rule);
References :
ConditionType
Advanced Google Services
Sheets API v4
If I misunderstand your question, I'm sorry.
The checkbox is the recently added Data Validation criterion. Interestingly enough, when I attempt to call the 'getDataValidation()' method on the range that contains checkboxes, the following error is thrown:
var rule = range.getDataValidation();
We're sorry, a server error occurred. Please wait a bit and try again.
In the meantime, you can work around this by placing a single checkbox somewhere in your sheet and copying its Data Validation to the new range. For example, if "A1" is the cell containing the checkbox and the target range consists of a single column with 3 rows:
var range = sheet.getRange("A1"); //checkbox template cell
var targetRange = sheet.getRange(rowIdex, colIndex, numOfRows, numOfCols);
range.copyTo(col, SpreadsheetApp.CopyPasteType.PASTE_DATA_VALIDATION);
var values = [["true"], ["false"], ["false"]];
targetRange.setValues(values);
Short answer
Add the checkbox from the Google Sheets UI, then use one of the copyTo
methods of Class Range.
Explanation
The Google Apps Script Spreadsheet service doesn't include a methods for everything that could be done through the Google Sheets user interface. This is the case of the Insert > Checkbox which is a pretty new feature.
Even the Record macro feature can't do this. The following was recorded one momento ago
/** #OnlyCurrentDoc */
function InsertCheckbox() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A1').activate();
/*
* Added to show the missing Insert > Checkbox step
*/
spreadsheet.getRange('B1').activate();
spreadsheet.getRange('A1').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
};
NOTE: If you don't want to pass all the cell properties (borders, formulas, background, etc. instead of SpreadsheetApp.CopyPasteType.PASTE_NORMAL use SpreadsheetApp.CopyPasteType.PASTE_DATA_VALIDATION.
Related Q on Stack Overflow
Google Sheets: Add a CheckBox with a script
function onEdit() {
var cell = SpreadsheetApp.getActive().getRange('A1');
var array =['☐','☑'];
// var rule = SpreadsheetApp.newDataValidation().requireValueInList(['☐','☑']).build();
var rule = SpreadsheetApp.newDataValidation().requireValueInList(array, false).build()
cell.setDataValidation(rule);
var valor = array[1];
// Logger.log(valor);
if(cell.getValue() == valor){
cell.offset(0, 1).setValue("Aprobado");
} else{
cell.offset(0, 1).setValue("Reprobado");
}
}
Easy:
//There are two ways, using Range or using current cell or sheet or similar
//First is using current cell
function VoF() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getCurrentCell().offset(1, 0, 499, 1).setDataValidation(SpreadsheetApp.newDataValidation()
.setAllowInvalid(true)
.setHelpText('TRUE or FALSE')
.requireCheckbox() //if you customize this is possible that you dont get the boxes and the verification data could fail,so keep them standar with TRUE and FALSE
.build());
};
//Second is using Spreedsheet ranges
function myFunction() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('G1:G11').activate();
spreadsheet.getRange('G1:G11').setDataValidation(SpreadsheetApp.newDataValidation()
.setAllowInvalid(false)
.requireCheckbox()
.build());
};
I agree that you have to workaround to create a checkbox. Another way maybe is to create a dropdown list.
function myFunction() {
var cell = SpreadsheetApp.getActive().getRange('A1');
var rule = SpreadsheetApp.newDataValidation().requireValueInList(['☐','☑']).build();
cell.setDataValidation(rule);
}
I am trying to get an Angular Bootstrap UI typeahead to match against multiple properties. If i have an array of objects like this:
{
"city":"New York",
"region":"NY",
"country":"USA"
},
{
"city":"London",
"region":"England",
"country":"UK"
}
Can typeahead match any of the 3 properties (city, region, country ) and if it does, return all as a string in the results dropdown.
If a user types "NY" it should return and display
New York, NY, USA
And if a user instead types "Lon" it should return and display
London, England, UK
I'm wondering if it is possible to do what this and what might be the best approach?
Note: The typeahead is set to match against leading characters.
1. define model
$scope.model.addresses = [
{"city":"New York","region":"NY","country":"USA"},
{"city":"London","region":"England", "country":"UK"}
];
2. define custom filter function
$scope.findAddress = function(keyword) {
return $filter('filter')($scope.model.addresses , {'$': keyword});
}
'$' - means find in all properties
3. and try to use in this way
<input typeahead="address for address in findAddress($viewValue)"/>
I am currently in the process of building a dashboard in R shiny. I want the user to be able to select from a list of experiments which are currently live, which will change over time. Therefore it has to be called from a dataframe (or something similar) which is generated by the code each day as lists start and stop.
I have the current code below, however this provides a number rather than the name, which I assume is a reference to the name, but I cannot understand how to get it displaying the name. When I use the list code it does not run as it states I must individually list each item, (assuming this is like the one that works below for user type.
Testids is currently a dataframe with 45 obs. of 1 variable.
Any ideas on how to resolve this?
Thanks in advance
library("shiny")
shinyUI(
pageWithSidebar(
headerPanel("Draft dash"),
# Sidebar with filters for test types
sidebarPanel(
selectInput("Test", "Experiment Name:",
c(Testids)
),
selectInput("User", "User Type:",
list("All users" = "All",
"Known users" = "KN",
"Unknown users" = "UN",
"New users" = "NW",
"Existing users" = "EX")),
As far as I can tell, selectInput("Test", "Experiment Name:", c(Testids) ) will show the entries of dataframe Testids instead of the column names, which I think is what you want. Use names(dataframe) to populate the SelectInput list with the column names.
server <- function(input, output) {
output$distPlot <- renderPlot({
hist(mtcars[,input$Select], col = 'darkgray', border = 'white')
})
}
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
selectInput('Select', 'Selection:', names(mtcars)),
selectInput("User", "User Type:",
list("All users" = "All",
"Known users" = "KN",
"Unknown users" = "UN",
"New users" = "NW",
"Existing users" = "EX"))
),
mainPanel(plotOutput("distPlot"))
)
))
shinyApp(ui = ui, server = server)