Google script spreadsheet - I need to run one script from multiple buttons but with different parameters - image

I have two buttons (Button1 and Button2) and one function: MyFunction(number). And I either need to pass a parameter to the function or find out what button the function was started from. Is it possible?
function MakePDF(number) {
var ui = SpreadsheetApp.getUi();
//Get Active Spreadsheet
var spreadSheet=SpreadsheetApp.getActiveSpreadsheet();
spreadSheet.getRange('B2').setValue(number); //HERE I NEED TO GET THE SPECIFIC NUMBER FROM 1 TO 100
//Get Sheet to print of the spreadsheets
var sheets=spreadSheet.getSheets();
var Faktura = spreadSheet.getSheetByName("Invoice");
var sheetID = Faktura.getSheetId();
//Export URL with Parameters
var spreadSheetId = spreadSheet.getId();
var URL = "https://docs.google.com/spreadsheets/d/"+spreadSheetId+"/export"+
"?format=pdf&"+
"size=7&"+
"fzr=false&"+
"portrait=true&"+
"fitw=true&"+
"gridlines=false&"+
"printtitle=false&"+
"sheetnames=false&"+
"pagenum=UNDEFINED&"+
"attachment=true&"+
"gid="+sheetID;
//the HTTP method for the request: get and headers : authorization : Bearer tokens to access OAuth 2.0-protected resources
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
//Return the data inside this object as a blob.
var response=UrlFetchApp.fetch(URL,params).getBlob();
//To set name of file
var VS = listOvladani.getRange('B6').getValue();
var firma = listOvladani.getRange('B5').getValue();
firma = removeDiak(firma);
firma = firma.toString().replace(/ /g, '-');
firma = firma.toString().replace(/\./g,'');
firma = firma.toString().replace(/,/g,'');
var namePDF = VS + "_" + firma + "_Autonapul.pdf";
// Load it to specific directory
var dir = DriveApp.getFoldersByName("Rucnifaktury").next();
var pdfFile = dir.createFile(response).setName(namePDF);
// Display a modal dialog box with custom HtmlService content.
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open ' + spreadSheet.getName() + '</p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful');
//Email it
/* MailApp.sendEmail('trnka#trnka.cz', 'Pokus', 'Nějaký text', {
attachments: [{
fileName: "Faktura_pokusna" + ".pdf",
content: response.getBytes(),
mimeType: "application/pdf"
}]
});
*/
}
More details More details More details More details More details More details More details More details More details More details More details More details

You can do it in a different way:
Replace buttons through checkboxes and bind to your script an onEdit(e) trigger which will automatically fire the script on each edit.
You can implement a statement to verify either the edited column was your checkbox column and if so - which checkbox has been checked.
Sample:
function onEdit(e) {
if(e.range.getColumn()==2&&e.range.getValue()==true){
Logger.log(e.range.getA1Notation());
}
}
References:
Event objects
getValue()
getColumn
A1 notation

You can use two more functions who just call the main function with a different parameter, so button 1 calls pressButton1 and button 2 calls pressButton2.
function MakePDF(number) {
//do stuff
}
function pressButton1(){
MakePDF(1);
}
function pressButton2(){
MakePDF(2);
}
This is the easiest way to handle the situation.

Related

How to identify an entity has quick create form enabled or not by Javascript?

I have some code below by which I am opening quick create form for entities if enabled but if not enabled I want to open in new window. I need to identify the entity has enabled quick create form or not on definition and how to do it by Javascript?
var entityFormOptions = {};
entityFormOptions["entityName"] = "contact";
entityFormOptions["useQuickCreateForm"] = true;
// will make it true if quick create form not enabled
entityFormOptions["openInNewWindow"] = false;
// Set default values for the Contact form
var formParameters = {};
// Open the form.
Xrm.Navigation.openForm(entityFormOptions, formParameters).then( function (success) { console.log(success); }, function (error) { console.log(error); });
I have found the solution, I can find IsQuickCreateEnabled through this api request:
[organization URI]/api/data/v9.0/EntityDefinitions

nativescript - how set global variables

I'm starting with nativescript with latest version.
I've finished tutorial on offical page, but now i have more questions than answers.
Can anybody tell me, what strategies can i use to set some variables, for example after succesfull login, how to set variable or even better, run some function that is doing checks globally, and not on every view or model file ?
I see that app.js is starting point for app, but looks like it cannot do any global checks ?
I think, second question is related :
Almost every model view file (file called as {viewname}).js is using:
var frameModule = require('ui/frame');
Is there a way to declare this once ? Or i have to run this every time when i need frame methods ? Or maybe if this is possible, lead to poor perforance?
Thanks for any advices.
NativeScript has a global Variable Scope.
To use it add global. in front of a variable name:
global.userName = "usernameXYZ";
To call it:
console.log("Username= "+global.userName);
Thanks Nikolay. Im using this pattern (maybe will help somebody)
register JS:
var page = require ("ui/core/view");
var frameModule = require('ui/frame');
var appSettings = require('application-settings');
exports.loaded = function(args) {
page = args.object;
};
exports.register = function() {
var userName = page.getViewById('userName');
var userPass = page.getViewById('userPass');
if (userName.text != '' && userPass.text != '') {
var name = userName.text;
var pass = userPass.text;
appSettings.setString('name', name);
appSettings.setString('pass', pass);
appSettings.setBoolean('auth', true);
var topmost = frameModule.topmost();
var navigationEntry = {
moduleName: "main-page",
context: { info: "something you want to pass to your page" },
animated: true,
transition: "curlDown",
clearHistory: true
};
topmost.navigate(navigationEntry);
} else {
alert('Please, fill form');
}
};
i use model as a global like this, in model.js (or whatever you want to call it)
`
var viewModel=require("data/observable");
var model= new viewModel.Observable();
module.exports= model;`
Then say in your login.js
` const model=require('./model')
const password = //a password from page
const userName = //a name from page
//after some logic to verify credentials set them accordingly as below
model.password=password
model.userName=userName
`
now if say you are navigated to home.js or any page for that matter, just call it whenever required like so const pass=model.password,name=model.userName all with courtesy from 'model.js'

Add row to Google Spreadhseet via API

I am building a Chrome extension which should write new rows into a Google Spreadsheet. I manage to read the sheet content but am not able to write an additional row. Currently my error is "400 (Bad Request)". Any idea what I am doing wrong here?
I have gone through the Google Sheets API documentation and other posted questions here but was not able to find any solution.
Here is the code which I use to GET the sheet content (this works):
function loadSpreadsheet(token) {
var y = new XMLHttpRequest();
y.open('GET', 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/values?access_token=' + token);
y.onload = function() {
console.log(y.response);
};
y.send();
}
And this is the code I try to POST a new row (gives me "400 - Bad Request"):
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',//'--END_OF_PART\r\n',
'<gsx:name>',foo,'</gsx:name>',//'--END_OF_PART\r\n',
'</entry>'].join('');
return atom;
};
var params = {
'body': constructAtomXML("foo")
};
url = 'https://spreadsheets.google.com/feeds/list/spreadsheet_id/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
Note: spreadsheet_id is a placeholder for my actual sheet ID.
Follow the protocol and to make it work.
Assume spreadsheet ID is '1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8'
First use the spreadsheet ID to retrieve list of worksheets:
GET https://spreadsheets.google.com/feeds/worksheets/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/private/full?alt=json
There you can read list of worksheets and their IDs. Let use the first worksheet from the example. You'll find its id in feed > entry[0] > link array. Look for "rel" equal 'http://schemas.google.com/spreadsheets/2006#listfeed'.
In my example the URL for this worksheet is (Worksheet URL): https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full
Now, to read its content use:
GET [Worksheet URL]?alt=json
Besides list-row feed, you'll also find a "post" URL which should be used to alter spreadsheet using list-row feed. It's the one where "rel" equals "http://schemas.google.com/g/2005#post" under feed > link.
It happens that it is the same URL as for GET request. In my case: https://spreadsheets.google.com/feeds/list/1TCLgzG-AFsERoibIUOUUE8aNftoE7476TWYKqXQ0xb8/ofs6ake/private/full. Just be sure to not append alt=json.
Now, to insert a new row using list-row feed you need to send POST with payload which is specified in docs. You need to send a column name prefixed with "gsx:" as a tag name. However it may not be the same as the column name in the spreadsheet. You need to remove any white-spaces, make it all lowercase and without any national characters. So to make your example work you need to replace <gsx:Name> with <gsx:name>.
Before the change you probably had the following payload message:
Blank rows cannot be written; use delete instead.
It's because the API didn't understand what the "Name" is and it just dropped this part of entry from the request. Without it there were no more items and the row was blank.
Alternatively you can read column names from the GET response. Keys from objects in feed > entry array that begins with gsk$ are columns definitions (everything after $ sign is a column name).
=================================================================
EDIT
To answer a question from the comments.
I've changed two things from your example:
function appendRow(token){
function constructAtomXML(foo){
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gsx="http://schemas.google.com/spreadsheets/2006/extended">',
'<gsx:name>',foo,'</gsx:name>',
'</entry>'].join('');
return atom;
};
/*
var params = {
'body': constructAtomXML("foo")
};
*/
var params = constructAtomXML("foo");
url = 'https://spreadsheets.google.com/feeds/list/'+spredsheetId+'/default/private/full?alt=json&access_token=' + token;
var z = new XMLHttpRequest();
z.open("POST", url, true);
z.setRequestHeader("Content-type", "application/atom+xml");
z.setRequestHeader("GData-Version", "3.0");
z.setRequestHeader("Authorization", 'Bearer '+ token);
z.onreadystatechange = function() {//Call a function when the state changes.
if(z.readyState == 4 && z.status == 200) {
alert(z.responseText);
}
}
z.send(params);
}
1) <gsx:Name> to <gsx:name>. Without it you'll receive an error.
2) params object should be a String! Not an object with some 'body' key. You just need to pass a value you want to send to the server.

How to use a confirmation button in Google Apps Script spreadsheet embedded scripts?

I have this Google Apps Script to send an email with a request to people I choose in a spreadsheet:
function sendRequestEmail() {
var data = SpreadsheetApp.openById(SPREADSHEET);
if(!employee_ID) {
employee_ID = getCurrentRow();
if (employee_ID == 1) {
var employee_ID = Browser.inputBox("Você precisa selecionar um assistido?", "Choose a row or type its number here:", Browser.Buttons.OK_CANCEL);
}
}
// Fetch variable names
// they are column names in the spreadsheet
var sheet = data.getSheets()[0];
var columns = getRowAsArray(sheet, 1);
Logger.log("Processing columns =" + columns);
var employeeData = getRowAsArray(sheet, employee_ID);
Logger.log("Processing employeeData = " + employeeData);
// Assume first column holds the name of the person
var email2Send = "pythonist#example.com";
var title = "Request by email";
var name = employeeData[0];
var mother_name = employeeData[1];
var message = "Hi, I have a request for you, " + name + ", this is... example";
// HERE THE
// CONFIRMATION BUTTON!!!
MailApp.sendEmail(email2Send, title, message);
}
And, before sending the email, I want a confirmation button, something like this:
function showConfirmation(name, email2Send) {
var app = UiApp.createApplication().setHeight(150).setWidth(250);
var msg = "Do you confirm the request to " + email2Send + " about " + name + "?";
app.setTitle("Confirmation of request");
app.add(app.createVerticalPanel().add(app.createLabel(msg)));
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
So, if user press OK, the app will execute the line MailApp.sendEmail(email2Send, title, message); and send an e-mail.
I have to admit my ignorance. I'm reading chapter 4 of the book "Google Apps Script" (Oreilly, by James Ferreira) on handlers. I've tried using an example provided in the documentation from Google (already deleted the code!). But I came across an error that I could not understand.
The code used were this sample:
var ui = DocumentApp.getUi();
var response = ui.prompt('Getting to know you', 'May I know your name?', ui.ButtonSet.YES_NO);
// Process the user's response.
if (response.getSelectedButton() == ui.Button.YES) ... DO THIS
I have some urgency in this simple project, so forgive-me for asking this question before research more for the answer (I'm searching for it while wating for the answer). So, how can I use a confirmation/cancellation button in this code?
The code snippet you showed is for document embedded UI, the equivalent (well... almost) class for spreadsheet context is Browser.MsgBox(prompt,buttons), see doc here, it will be simpler than create a Ui + a handler function... even if the layout and appearance are fairly basic it's easy and efficient.
In your code it becomes :
...
var confirm = Browser.msgBox('send confirmation','Are you sure you want to send this mail ?', Browser.Buttons.OK_CANCEL);
if(confirm=='ok'){ MailApp.sendEmail(email2Send, title, message)};
...

Get all entries for a given name in firefox form history

Is there a way I can find out all elements of a given name in teh form history. In my firefox addon, I am adding some elements in the form-history under a specific name - lest say "search-description".
I now want to get all the elements I added under this name. I see that I can get a history object :
this.Ci = Components.interfaces;
this.Cc = Components.classes;
var historyObj = this.Cc["#mozilla.org/satchel/form-history;1"].getService(this.Ci.nsIFormHistory2 || this.Ci.nsIFormHistory);
But the nsIFormHistory or nsIFormHistory2 interfaces do not have any function like:
getAllEntries(name)
Anyone can help me out in this?
Usually, nsIFormHistory2.DBConnection property is used for querying, you access the SQLite table directly. Something like this (untested):
var completionListener =
{
handleCompletion: function(reason) {},
handleError: function(error) {},
handleResult: function(result)
{
var values = [];
while (true)
{
var row = result.getNextRow();
if (!row)
break;
values.push(row.getResultByName("value"));
}
alert("Autocomplete values: " + values);
}
};
var query = "SELECT value " +
"FROM moz_formhistory " +
"WHERE fieldname='search-description'";
var statement = historyObj.DBConnection.createAsyncStatement(query);
historyObj.DBConnection.executeAsync([statement], 1, completionListener);
Note that using async API is recommended here, querying the database might take time.

Resources