Create a Dialog box with custom buttons and Links - google-apps-script

So I have an internal emailing list that I want to subscribe new employees to and unsubscribe employees that have left.
I'm using a google sheet with a check box to do this. Mainly because this sheet is already used in the HR process, so it's easy to remember to do.
When the check the box is checked I want a dialog box to pop up with a buttons that says
Subscribe and Unsubscribe. These buttons are linked to locations within the emailing tool that allows people to subscribe or unsunscribe.
The scribe I have at the moment is
var result = ui.alert
(
'What would you like to do?',
'Subscribe a new Employee or' + "\n" + 'Unsubcribe an employee thats left',
ui.ButtonSet.Subscribe_Unsubscribe
);
if (result == ui.Button.Subscribe)
{
}else
{
ui.alert('Employee has been removed from the internal mailing list');
}
}
I'm not sure how if by changing the button set names work this way and I dont know how to assign a link to the buttons either.
Looking forward to your responses!!!

Step 1:
First you would need to create an installable trigger that would execute a function in GAS whenever a cell is edited.
You can find an explanation / reference on Installable Triggers here:
Installable Triggers
Why installable triggers? Because you would need to connect to an email service, which requires authorization.
Sample Code:
/**
* Creates a trigger for when a spreadsheet is edited.
*/
function createSpreadsheetEditTrigger() {
var ss = SpreadsheetApp.getActive();
ScriptApp.newTrigger('myFunction')
.forSpreadsheet(ss)
.onEdit()
.create();
}
Step 2:
To create custom dialog boxes you need to create the HTML file from scratch in GAS, the IDE allows you to create HTML files from the menu.
Then in your script you would need to use getUi().showModalDialog to display the dialog box.
I have some sample code in a Stack Overflow post here: Stack Overflow
Note that the HTML would need both onclick="google.script.run" and onclick="google.script.host.close()" parameters to execute functions within Apps Script.
References:
showModalDialog()
Templated HTML
Communication between HTML and Apps Script

Related

Google script embedded in google sheet adding a menu item

What I tried is adding some functionality to my google sheet (creating events and pushing them to the google calendar). Everything works, but when I close the script editor my menu disappears.
I created the menu items like so:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Sync to Calendar')
.addItem('Create Events Now', 'CreateEvent')
.addItem('Delete All Events in Calendar', 'DeleteAllEvents')
.addToUi();
}
That works just fine, but I would like to close the script and also when I share the spreadsheet, the member shall be presented with the menu to click and execute the functions. Anyone has a solution how to make that permanent? (without publishing the script which would be an overkill in my opinion)
In some cases OnOpen doesn't run automatically unless the editor has authorized the script. In this case, you need to give editors a way to trigger the script, so they may authorize it, before onOpen will run automatically. You can either give them instructions to do this manually through the script editor, or you can insert a "button" into the sheet.
To do this "button" - insert an drawing into the sheet (the "button"), bind the drawing to your script, and have first time users click the drawing.
In your spreadsheet, click "Insert" -> "Drawing"
Draw a "button" image with useful text for end users ("Show custom menu" or "No menu? Click here!", etc.)
Place the drawing on your spreadsheet in a visible/convenient location.
Click the "three dots" on the drawing and select "Assign Script"
Enter the name of the function (eg OnOpen)
If a user opens the sheet and doesn't see your menu, they can click this "button" to activate the script. They'll be prompted to authorise the script as needed, then the menu will show from that point forward. They should only need to click the button the very first time they open the sheet, unless the scopes change or they manually remove authorization in account settings.
onOpen is a reserved word for a function to be called automatically when a Google Sheets spreadsheet is opened by the spreadsheet owner or editors, it will not run for viewers.
You should check that in the project there isn't any other function named onOpen otherwise another function declaration could be executed instead of the one that you expect.
Reference
https://developers.google.com/apps-scripts/guides/triggers
The suggested answer from Cameron Roberts works as a workaround.
Although in my case the problem was that the script trigger for onOpen was missing. I had to edit the script trigger within the script I wrote. In the script editor go to "Edit" -> "Current projects triggers" and add a trigger for the onOpen function with an event "on open". Apparently that was missing in my case, after that edit, it worked like a charm.

Can I use Slides API to add an "Agree to Terms" dialogue before allowing viewer access to a Slides presentation?

I have a Google Slides presentation that I'd like to gate with a request to agree to "Terms & Conditions" before viewing. (The dialogue box would include an external link to the legal fine print.)
I see that with Google App Script adding a dialogue box is possible, but if one can be customized in this manner is unclear to me.
Thanks in advance for any help on this.
You want to open a dialog, when users open the Google Slides.
In this case, users are logged in to each Google account.
You want to make users show "Terms & Conditions" by the external link.
When users click "ok" button, when users reopen the Google Slides, you don't want to open the dialog.
When users click "cancel" button, when users reopen the Google Slides, you want to open the dialog.
You want to use a custom dialog for this.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Issue and workarounds:
In order to open the custom dialog when users open the Google Slides, it is required to use the installable trigger. But at Google Slides, unfortunately, in the current stage, the OnOpen event trigger cannot be used as the installable trigger. By this, when users open the Google Slides, the custom dialog cannot be opened. It seems that this is the current specification. So in order to achieve abour your goal, it is required to think of the workaround. In this answer, I would like to propose the following 2 workarounds.
Workaround 1:
Fortunately, at Google Slides, the simple trigger can be used instead of the installable trigger which cannot be used. In this case, the OnOpen event trigger can be used as the simple trigger. So in this workaround, the built-in dialog is used with the simple trigger.
Sample script:
Please copy and paste the following script to the container-bound script of the Google Slides and save it. When you open the Google Slides, a dialog is opened. When "ok" is clicked, keyObject is set to the PropertiesService. By this, when you open the Google Slides again, the dialog is not opened. In this case, getUserProperties() is used. So keyObject can be used for each users.
function onOpen() {
var keyObject = {key1: "value1"}; // Here, key and value for checking whether user had clicked "ok" button.
var prop = PropertiesService.getUserProperties();
var value = prop.getProperty(Object.keys(keyObject)[0]);
if (value != keyObject.key1) {
var ui = SlidesApp.getUi();
var result = ui.alert('sample title', 'Please check this link.\nhttps://###/', ui.ButtonSet.YES_NO);
if (result == ui.Button.YES) {
ui.alert('"ok" was clicked.');
prop.setProperties(keyObject);
} else {
ui.alert('"cancel" was clicked.');
}
}
}
In this case, the URL cannot be clicked. So user is required to access to the URL. I think that this is the limitation when this workaround is used.
If you want to delete keyObject. Please use the following script.
function deleteProperty() {
var keyObject = {key1: "value1"};
var prop = PropertiesService.getUserProperties();
prop.deleteProperty(Object.keys(keyObject)[0]);
}
Workaround 2:
In this workaround, the built-in dialog and the custom menu are used with the simple trigger. In this case, the custom dialog is used.
Sample script:
Please copy and paste the following script to the container-bound script of the Google Slides and save it. When you open the Google Slides, a dialog is opened. The dialog shows "Please open dialog from the menu.". Users click "ok" button and open the custom dialog from the custom menu. When "ok" is clicked at the custom dialog, keyObject is set to the PropertiesService. By this, when you open the Google Slides again, the dialog is not opened. In this case, getUserProperties() is used. So keyObject can be used for each users.
function onOpen() {
var keyObject = {key1: "value1"};
var prop = PropertiesService.getUserProperties();
var value = prop.getProperty(Object.keys(keyObject)[0]);
if (value != keyObject.key1) {
var ui = SlidesApp.getUi();
ui.createMenu('Open dialog').addItem('Open dialog', 'openDialog').addToUi();
var result = ui.alert('sample title', 'Please open dialog from the menu.', ui.ButtonSet.OK);
}
}
function openDialog() {
var ui = SlidesApp.getUi();
var html = 'link<input type="button" value="ok" onClick="ok()"><input type="button" value="cancel" onClick="cancel()"><script>function ok() {google.script.run.withSuccessHandler(()=>google.script.host.close()).setProp()}function cancel() {google.script.host.close()}</script>';
ui.showModalDialog(HtmlService.createHtmlOutput(html), "sample");
}
function setProp() {
var keyObject = {key1: "value1"};
var prop = PropertiesService.getUserProperties();
prop.setProperties(keyObject);
}
In this case, the URL can be clicked. But in order to open the custom dialog, it is required to open it from the custom menu. I think that this is the limitation when this workaround is used.
Note:
Above scripts are the simple scripts for testing the workaround. So please modify them for your actual situation.
References:
Simple Triggers
Installable Triggers
Alert dialogs
Custom dialogs
If I misunderstood your question and this was not the direction you want, I apologize.

Button that performs a function (on slides)

I saw that in the spreadsheet you can create a drawing and link to a function in the script.
I need to: Create a button or link where clicking it will perform a function in the script.
It will be a simple email sending function.
Example: When the user clicks the button or link in the presentation, they receive an email from them.
There isn't a way to assign a script to a button in Google Slides in the same way as there is in Google Sheets.
The only alternative would be to use either a simple or installable trigger depending on your needs.
Google Slides only has compatibility with the onOpen() and onInstall() simple triggers which you can see here, though you would be able to send the mail with the built-in Apps Script library as such:
function sendEmail() {
MailApp.sendEmail("username#domain.com", "subject", "body");
}

Displaying a Google form on sheets

I am creating a form for users to input information on a Google spreadsheet. They will access the spreadsheet and then click on an image that is linked to a script. When the image is clicked, I want a form to appear. Then I want the input from the form to be accessible in the script.
I am able to create a form but the form does not appear on the sheet. Here is the code thus far for the GS script
function startForm() {
var form = FormApp.create('myForm');
var item = form.addCheckboxItem();
item.setTitle('What would you like to do?');
item.setChoices([
item.createChoice('Budget Inquiry'),
item.createChoice('Add Purchase')
]);
var choices = item.getChoices();
// then I can respond to the user's choice
}
I would like this simple form to just appear on the google sheet. Any input would be appreciated.
Instead of creating you own form with script, just go to the insert menu of your spreadsheet and select form. Enter you question and your two choices. Close the form. You will see a form response sheet created in your spreadsheet. Also, a menu item Form will appear on your menu. Then go to the script editor and from the menu select Resources. Select Current Project Triggers and set a new trigger for onFormSubmit. You can then enter a function onFormSubmit to do whatever you want done when the form is submitted getting data from the form response sheet. There is plenty of documentation you can Google.
The way in Google Sheets to display external content other than images and Google Drawings is by creating a dialog or sidebar with the related content embeded.
There is a similar question that includes an answer that shows how to do this:
Single Google Form for multiple Sheets

Add custom Data to Google Sheet once Form is filled

I am using a Goofle form that receives applications from users, once the form is submitted I am using Google form submission trigger to notify. It has some questions like (facebook profile link)
But while sending a notification I don't want those links to be appeared just the same way user enters, instead something like Facebook, twitter (text as hyperlinked.) should appear
I already know about onFormsubmit() function, but not sure how to use, help me out please.
For example:
Cell A2 has user submitted facebook profile link using the form.
I want Column B2 to automatically generated as =hyperlink(A2, "Facebook")
The same thing should happen like A3 to B3 whenever user submits a form.
Ok after a bit of digging and testing, I believe I got a solution for you since you use the "Yet Another Mail Merge" (aka YAMM) add-on. Here it goes:
Firstly make sure your Form is setup properly and linked to a Google Sheet. After all questions have been created, add another column to your sheet, and call it 'Hyperlink' or whatever you please (just remember it for later). We will make use of the form submit trigger in the script editor along with some code.
Here's the code:
function onFormSubmit(e)
{
var r = e.range;
var v = e.namedValues;
var link = v['Link'];
// For testing purposes, this part was apart of my form,
// I'd assume you'd want to change it to something more
// usable in your case. Notice that I refer to the values
// by the name of the question they preside in.
var friendlyName = v['Friendly Name'];
var rngHyper = getCellRngByCol(r, 'Hyperlink');
// See below for the meaning of the boolean
addHyperlink(rngHyper, link, friendlyName, true);
}
// Will only return one cell no matter the range size.
// Perfect for onFormSubmit(e) use case.
function getCellRngByCol(rng, col)
{
var aRng = SpreadsheetApp.getActiveSheet().getDataRange();
var hRng = aRng.offset(0, 0, 1, aRng.getNumColumns()).getValues();
var colIndex = hRng[0].indexOf(col);
return SpreadsheetApp.getActiveSheet().getRange(rng.getRow(), colIndex + 1);
}
// Add some form of hyperlink reference to one particular
// cell, passed as a range object
function addHyperlink(rng, link, name, useFormula)
{
if (useFormula)
{
// If useFormula is TRUE, use Google Sheet HYPERLINK formula,
// only if you are sure all URL's are formated properly,
// and include HTTPS/HTTP/WWW. Also looks more pleasing in Google Sheet.
var formula = '=HYPERLINK("<<URL>>", "<<NAME>>")';
formula = formula.replace('<<URL>>', link).replace('<<NAME>>', name);
rng.setFormula(formula);
}
else
{
// Else use HTML <a> tag with hyperlink referencing, which should transform
// any URL passed as a clickable hyperlink within email. Not very visually
// appealing in Google Sheet.
var value = '<<NAME>>';
value = value.replace('<<URL>>', link).replace('<<NAME>>', name);
rng.setValue(value);
}
}
Then set the trigger, which will probably ask for authorization after saving:
Next, save the script and then put in a test submission through your form to see that the link is created properly, or as desired. Afterwards clear the rows of the spreadsheet (not the header) and remove all responses of the Form itself (not necessary, but keeps things organized for testing purposes).
Now, install the YAMM add-on. It should then add a new column at the end of your sheet called 'Merge satus'. Before setting up the email notification on submit, we need to create your email template. Open up GMAIL, create an email with the desired fields and layout and save it as a draft. Here's what I did as an example:
I'm sure you're familiar with how this add-on, works so I shouldn't need to explain too much here.
After the draft has been created and saved, go back to the Google Sheet attached to the Form. Go to Add-ons > YAMM > Configure form submission notifications. I chose the 'Notify one or more addresses of all responses' option which are tied to the 'To:' emails preset in the draft. Select your draft from the drop down, fill in sender name if needed, AND (very important!!) check the 'Wait until a specific column is filled before sending the email' check box. Make sure to select the Hyperlink column (or whatever you chose to name it earlier). Here's my setup for reference:
Save it, test it, and ta-da. This simple formatting for hyperlinks has been resolved! :D