I'm not really well-versed with codes and I just wanted to try this out for my team. What I have is just a simple code that pops up an alert message (with OK button) everytime we open our Google Spreadsheet. What I wanted to happen is when we click "OK", it will open a link in a new tab. Here's my "script editor" code:
function onOpen() {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var ui = SpreadsheetApp.getUi().alert('Welcome to HAVENLY Offshore Team Workspace! Check out our CONFLUENCE updates today!');
}
Please help me achieve my ultimate goal here, I've been trying to find a solution for hours already. Thanks in advance!
You can do this if you use a custom dialog instead of an alert. Custom dialogs are much more powerful by allowing you to define your own html. Just create the following files in the script attached to the sheet.
Code.gs
function onOpen() {
openWelcomeDialog();
}
function openWelcomeDialog() {
// get the html from the file called "Pages.html"
var html = HtmlService.createHtmlOutputFromFile('Pages');
// open the dialog
SpreadsheetApp.getUi()
.showModelessDialog(html, "Welcome to HAVENLY Offshore Team Workspace!")
}
Pages.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<!-- target="_blank" directs the link to a new blank tab -->
<a target="_blank" href="http://stackoverflow.com/questions/17711146/how-to-open-link-in-new-tab-on-html">
Check out our CONFLUENCE updates today!
</a>
</body>
</html>
Update
You can also close the dialog when the user clicks on the link with an onclick event handler:
<a onclick="google.script.host.close()" target="_blank" href="||url||">
Check out our CONFLUENCE updates today!
</a>
function onOpen(){
confluencePopup()
}
function confluencePopup(){
// will display the dialog box with html text
var text = "Welcome to HAVENLY Offshore Team Workspace! Check out our CONFLUENCE updates today!'"
var url = "https://stackoverflow.com/questions/40888267/need-to-link-a-website-to-the-ok-button"
var rawHTML = '<a onclick="google.script.host.close()" target="_blank" href="' + String(url) + '">' + text + '</a>'
var htmlSerivce = HtmlService.createHtmlOutput(rawHTML)
SpreadsheetApp.getUi()
.showModelessDialog(htmlSerivce, "Welcome")
}
Change the url to your link, and text to the anchor text you would like. You can then just call this function in your onOpen() function. When run it will display a popup with your anchor text, and link to your page.
You may need to configure permissions to run the pop-up. See Google's documentation for that information. Simply you need to add oauthScopes to your appsscript.json file.
Edit: this can be altered to change the link dynamically with a variable, and does not require an additional file to run.
Related
I would like to add a horizontal scrollbar that will provide the values 0-365 based on its position and use this value for calculation.
I am creating a Gantt chart, the same as is on the page https://www.vertex42.com/ExcelTemplates/excel-gantt-chart.html
There is a horizontal scrollbar that helps "to move" with the calendar.
I have put there a number that I must change manually. I haven't found any solution on the internet.
This kind of control is simply not available natively within Google Sheets. I found a recent response from the Google Support Forums to indicate this is still the case.
If you want to build this functionality out yourself, it is actually now possible to do so, by taking full advantage of the Apps Script platform and their Google Sheets and HTML Service scripting APIs. You can create a dialog box with HTML and JS, which can have any inputs you want, including range sliders, and it can send the values back to the Google Sheet script, which can then save it to a cell. I put together a barebones test to make sure it would work, and it does:
I used Menu -> Tools -> Script Editor, and then created these two files:
Code.gs:
// Trigger dialog to be added to menu on file open
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('Dialog')
.addItem('Open', 'openDialog')
.addToUi();
}
function openDialog() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi()
.showModalDialog(html, 'Dialog title');
}
function saveSliderVal(updatedVal){
var sheetToSaveTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Gantt');
if (!sheetToSaveTo){
sheetToSaveTo = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
}
var cellToSaveTo = sheetToSaveTo.getRange('A1:A1');
cellToSaveTo.setValue(updatedVal);
}
index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<script>
function update() {
document.getElementById('val').innerText = document.getElementById('input').value;
}
function save() {
// Call sheet function
google.script.run.saveSliderVal(parseInt(document.getElementById('input').value, 10));
}
</script>
<input id="input" type="range" min="0" max="365" onchange="update()" oninput="update()" value="0"
step="1" /> <span id="val">0</span>
<br />
<button id="save" onclick="save()">Save to Gantt</button>
</body>
</html>
Then reload the sheet after saving your script, and you should see Dialog -> Open as a new menu item. Clicking it will bring up your custom HTML.
I am trying to get the URL to change depending on the results of a function.
If the href is a string, it will go to the google site page I want. Using a function however does not result in the same behaviour. Can anyone tell me where I am going wrong?
Script HTML
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<?var previewURL = PageForPreview();?><a href="#" onClick="window.open<?=previewURL?>" id="link" target="_blank" ></a>
<!-- < ?var previewURL = PageForPreview();?><a href="< ?=previewURL?>" id="link" target="_blank" ></a> document.location.href=//-->
<!-- <a href="#" onClick="document.location.href=PageForPreview();" id="link" target="_blank" ></a>//-->
<!-- <a href="https://sites.google.com/a/ENTER A SITE" id="link" target="_blank" ></a> //-->
</body>
<script>
document.getElementById("link").click();
//google.script.host.close();
</script>
</html>
Code.gs
////### go to preview page
function PageForPreview() {
var site = SitesApp.getActiveSite();
var newchildPages = site.getAllDescendants();
for(var ii in newchildPages) {
if (newchildPages[ii].getName() === "PreviewName") {
var arrLatest = ii;
}
}
var previewURL = newchildPages[arrLatest].getUrl();
Logger.log("prev = "+previewURL);
return previewURL;
}
It is my intention to have a button on a google site that will run a web app. The script runs okay until i try to open the page (section above) but then just displays the current page in a new window. When I deploy the code from the script editor, it works as expected using a text string for the site URL but with the function, it opens the macro url in a new window and then another window with the url https://n-ycp7azn7ycatih3bdzb2ibru6gld2ohyqxhk4xy-0lu-script.googleusercontent.com/userCodeAppPanel#
So I have a problem with the string in the href not acting in the same way and also the button on my page not going to the preview page even with the href as a string.
My next thing to investigate will be JSONP but I have very little experience with any coding. https://developers.google.com/apps-script/guides/content#serving_jsonp_in_web_pages Any guidance appreciated.
Edit
I am now able to get the desired page shown when deploying the web app from the script editor. Still can't get it to show when pressing a button on the google site to deploy the web app. Not sure if it's something with my code or the HTML for the button (or it just isn't possible).
return HtmlService.createHtmlOutput('<!DOCTYPE html><html><head><base target="_top"></head><script>'
+'var a = document.createElement("a"); a.href="'+PageForPreview()+'"; a.target="_blank";'
+'if(document.createEvent){'
+'var event=document.createEvent("MouseEvents");'
+'event.initEvent("click",true,true);'
+'a.dispatchEvent(event);'
+'}else{'
+'a.click()'
+'}'
//+'google.script.host.close();'
+'</script></html>').setWidth( 90 ).setHeight( 10 );
output.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
SpreadsheetApp.getUi().showModalDialog( myhtml, "Please Wait..." );
I want to take user input (HTML specifically) using either:
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Paste HTML below');
or
var input = Browser.inputBox('Paste HTML below', Browser.Buttons.OK_CANCEL);
These work fine for small inputs, however when copying over the entire HTML for a page of interest an error occurs (in each case). This error cannot be caught, it simply crashes the script.
Do you know why this is happening? I can't find anything in the docs that mention limits on input size.
Any experience doing this a different way?
Edit: as per a suggestion in the comments, I have tried another method (below). This also fails (with no error message) when passed large input.
First I set up Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Paste Sitemap Content Below
<textarea id="user-input-box" rows="4" cols="50"></textarea>
<script>
function logToConsole() {
var userInput = document.getElementById("user-input-box").value;
google.script.run.doSomething(userInput);
}
</script>
<input type="button" value="Close" onclick="logToConsole();google.script.host.close();" />
</body>
</html>
Then in file Code.gs
function testDialog() {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi()
.showModalDialog(html, 'My custom dialog');
}
function doSomething(userInput){
Logger.log(userInput);
}
I just ran into the same problem and couldn't log the error. In my case as is yours, you're calling your logToConsole() function and then directly after you're closing the dialog by using google.script.host.close();
google.script.host.close() is the problem. For some reason it can cancel the script execution - this typically happens when you're sending a lot of data back. The trick is to use a successHandler when you call your script which then calls google.script.host.close(). This way, the data transfer from the dialog finishes correctly and when you call withSuccessHandler(), that callback closes the dialog. Try this amendment to your code:
<script>
function logToConsole() {
var userInput = document.getElementById("user-input-box").value;
google.script.run.withSuccessHandler(closeDialog).doSomething(userInput);
}
function closeDialog() {
google.script.host.close();
}
</script>
<input type="button" value="Close" onclick="logToConsole()" />
This function in a google sheet does popup a window with the form, but the submit button is dead. What is missing that will make this window a live one?
function launchForm() {
var formID = '1YznrnFFIfXLpsZfsIZ4xjhlwmi8eLv_nTuOjDKGhwIc';
var form = FormApp.openById(formID);
var formUrl = form.getPublishedUrl();
var response = UrlFetchApp.fetch(formUrl);
var formHtml = response.getContentText();
var htmlApp = HtmlService
.createHtmlOutput(formHtml)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Ta Daaa!')
.setWidth(500)
.setHeight(650);
SpreadsheetApp.getUi().showModalDialog(htmlApp, 'Query window');
}
The function is hooked to a menu item and clicking on that item does bring up the form over the sheet, as does running the script from the script project attached to the sheet.
menuEntries.push({name: "Launch Query form", functionName: "launchForm"});
This particular form is simple, only three fields. So I could consider using HTML service to build an HTML and I see lots of questions about that not working either, so I can probably work that out. However, I have other forms that are a lot more complex and being able to simply call a regular Google form from within the spreadsheet is what I'd rather do.
Embed the URL of the Google Form into the HTML of the dialog box:
Code.gs
function launchForm() {
var htmlApp = HtmlService
.createHtmlOutputFromFile('InputForm')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Ta Daaa!')
.setWidth(500)
.setHeight(650);
SpreadsheetApp.getUi().showModalDialog(htmlApp, 'Query window');
}
InputForm.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<iframe src="https://docs.google.com/forms/d/e/FormIDHere/viewform?embedded=true" width="760" height="500" frameborder="0" marginheight="0" marginwidth="0">Loading...</iframe>
</body>
</html>
In "New" Google Forms you can get the IFRAME tag to embed the Google Form by clicking the "Send" button at the top right, and then clicking the third tab "<>"
I have a list of records in multiple sheets (same workbook).
I currently have a dropdown menu within my googlesheet where if you select one of the records it will delete the row with that record.
However, I would like to give the option to either move it to another sheet or delete it. I was trying to use UiApp but then found out alot of the options are deprecated and that now I have to use HTMLService.
So what I'm looking to do is, once I select a record, have a popup that has two options.
Option 1 : a Move option (button) with a dropdown of the names of the other sheets within the workbook that will then move that record to that sheet
Option 2 : Delete the record
Option 3 : Cancel.
Is this possible? and if so, would someone be able to guide me to the right direction or a similar example so I can try and figure out how to get that going?
You can try creating a Custom dialogs
A custom dialog can display an HTML service user interface inside a Google Docs, Sheets, or Forms editor.
Custom dialogs do not suspend the server-side script while the dialog is open. The client-side component can make asynchronous calls to the server-side script using either the google.script API for HTML-service interfaces or server handlers for UI-service interfaces.
Code.gs
function onOpen() {
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.createMenu('Custom Menu')
.addItem('Show dialog', 'showDialog')
.addToUi();
}
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'My custom dialog');
}
Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select>
<option>Delete</option>
<option>Move</option>
</select>
</body>
</html>
With that, try reading about HTML Service: Communicate with Server Functions
google.script.run is an asynchronous client-side JavaScript API that allows HTML-service pages to call server-side Apps Script functions. The following example shows the most basic functionality of google.script.run — calling a function on the server from client-side JavaScript.
Here is a sample code for form:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
// Prevent forms from submitting.
function preventFormSubmit() {
var forms = document.querySelectorAll('form');
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener('submit', function(event) {
event.preventDefault();
});
}
}
window.addEventListener('load', preventFormSubmit);
function handleFormSubmit(formObject) {
google.script.run.withSuccessHandler(updateUrl).processForm(formObject);
}
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
</head>
<body>
<form id="myForm" onsubmit="handleFormSubmit(this)">
<input name="myFile" type="file" />
<input type="submit" value="Submit" />
</form>
<div id="output"></div>
</body>
</html>
Hope this helps!