Google Apps Script: Use the sidebar to create a new sheet - javascript

I want to create a new sheet in my spreadsheet with the sidebar. I'm new to working with the sidebar so I'm not sure how to do it.
Code.gs:
function createSheet(sheetName) {
var sheet = ss.getSheetByName(sheetName)
if (!sheet) {
ss.insertSheet('Lookup: ' + sheetName)
}
}
Page.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h3>Create Partial Vlookup Table</h3>
<input id="myData">
<button onclick="createLookup()">Click</button>
<script>
function createLookup(){
var myData = document.getElementById('myData').value
google.script.run.withSuccessHandler(createSheet(myData))
}
</script>
</body>
</html>
I'd appreciate any help I can get with this issue!

I believe your goal as follows.
You want to insert new sheet in the active Spreadsheet using the sidebar.
Modification points:
In order to run the function at Google Apps Script side, please modify google.script.run.withSuccessHandler(createSheet(myData)) to google.script.run.withSuccessHandler(function).createSheet(myData).
In your script of createSheet, it seems that ss is not declared.
When your script is modified with above points, it becomes as follows.
Modified script:
HTML & Javascript side:
In this case, please modify createLookup as follows.
function createLookup(){
var myData = document.getElementById('myData').value;
google.script.run.withSuccessHandler(alert).createSheet(myData); // Modified
}
Google Apps Script side:
function createSheet(sheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // Added
var sheet = ss.getSheetByName(sheetName);
if (!sheet) {
ss.insertSheet('Lookup: ' + sheetName);
}
return "ok"; // Added
}
By above modification, when the button on the side bar by inputting a value is clicked, a new sheet is inserted in the active Spreadsheet. And, ok is returned and you can see it at the alert dialog on the browser.
When you want the script for opening the side bar, how about the following script?
function openSidebar() {
SpreadsheetApp.getUi().showSidebar(HtmlService.createHtmlOutputFromFile("Page"));
}
Reference:
Class google.script.run

Related

what is the error in this web app script to give the desired effect?

enter image description herewe've tried to write a script for a web app to a specific spreadsheet
the code is 2 files one in js
function doGet() {
return HtmlService.createHtmlOutputFromFile("page");
}
//function userClicked(name) {
//var url = "https://docs.google.com/spreadsheets/d/1T3AX_YBC8703g6N7sKot41tXUh6XN4zpcBF2V-_7iJ8/edit#gid=0";
//var ss = SpreadsheetApp.openByUrl(url);
//var ws = ss.getSheetByName("Data");
//ws.appendRow([name])
//Logger.log(name + "Clicked Run Button");
//}
function userClicked() {
Logger.log("Someone Clicked the button");
}
and the other in html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Welcome</h1>
<button id="btn">RUN !!</button>
<script>
function doSomething() {
google.script.run.code.userClicked();
}
document.getElementById("btn").addEventListener("click", doSomething());
</script>
</body>
</html>
we can't get the desired action when run button is clicked
we don't know if it's the declaration of functions or summoning them
please help guide to rectify the error
this is yje project link for further analysis
https://script.google.com/d/1daP7bLBlL46av4Wc6-Pr9-z9lg6JyMY44FUtfA08fnKRKLeMuCTxH3LY/edit?usp=sharing
According to the Google Script client side API documentation, the path to call the App Script function is google.script.run.yourFunction() so in your html file. Also you are invoking the function straight away and passing the result of it to addEventListener(), instead of passing the function itself. The script should be this:
function doSomething() {
google.script.run.userClicked();
}
document.getElementById("btn").addEventListener("click", doSomething);

App Script - Open Url in new Tab from Google WebApp (without assigned Spreadsheet)

I want to create a WebApp, that does the following:
User clicks button on WebApp to run script
Get User eMail
Create new Google Spreadsheet (name=eMail)
get Url of that Spreadsheet
Automatically open Url in new Tab
Step 5 is where I am stuck.
I have used window.open(url) before, however that only seems to work when you run code via a Spreadsheet. What I wanna do is displaying the button on my .html and run everything only with the WebApp but I can't do that because I can not use SpreadsheetApp.getUi() from that context.
Is there another way to do this?
Here is the Error im getting:
EDIT: Seems I had some minor mistakes in my Code.gs I think i fixed that now. Still same issue tho
Thank you guys in advance! :)
Here is some sample code:
Code.gs
function doGet(e) {
return HtmlService.createHtmlOutputFromFile("page");
}
function clickEvent () {
const lock = LockService.getScriptLock();
lock.tryLock(5000);
if (lock.hasLock()){
var email = Session.getActiveUser().getEmail();
var url = createFile(email);
openUrl(url); //THIS ONLY WORKED FROM WITHIN SPREADSHEET
lock.releaseLock();
}
}
function createFile(email){
var newSS= SpreadsheetApp.create(email);
var file = DriveApp.getFileById(newSS.getId());
var url = file.getUrl();
return url
}
function openUrl( url ){ //HAS TO CHANGE
var html = HtmlService.createHtmlOutput('<html><script>'
+'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";'
+'if(document.createEvent){'
+' var event=document.createEvent("MouseEvents");'
+' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+' event.initEvent("click",true,true); a.dispatchEvent(event);'
+'}else{ a.click() }'
+'close();'
+'</script>'
// Offer URL as clickable link in case above code fails.
+'<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+'</html>')
.setWidth( 90 ).setHeight( 1 );
SpreadsheetApp.getUi().showModalDialog( html, "Opening ..." );
}
}
page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Click Button!</h1>
<button id="btn">Run</button>
<script>
document.getElementById("btn").addEventListener("click",sendRequest);
function sendRequest(){
google.script.run.clickEvent();
}
</script>
</body>
</html>
Get url from app script and open spreadsheet in new tab wit JavaScript
Update app script function
function clickEvent () {
const lock = LockService.getScriptLock();
lock.tryLock(5000);
if (lock.hasLock()){
var email = Session.getActiveUser().getEmail();
lock.releaseLock();
return createFile(email);
}
}
Also update JavaScript Code
function sendRequest(){
google.script.run.withSuccessHandler(
function (link) {
window.open(link, '_blank').focus();
}
).testCSV3();
}
Reference: Communicate with Server Functions

How do I grab URL in Apps Script (.gs) and hand it to a .html script?

This is my first question here and I am pretty new to js and html so please excuse if I'm missing something obvious.
Goal: I want to create a script, that creates a Folder in your Google Drive but only if it's not already existing. In that folder it should create a .txt that contains certain information. After that, I want a new Tab to automatically open the URL of the newly created txt-file.
If I insert a normal URL in my .html (like "https://www.google.com") it all works perfectly fine. However I'm stuck at the part where the Apps Script hands over the grabbed Url of the newly created file to my html.
Any help is appreciated!
Google Apps Script Code (Code.gs):
function myFunction() {
var FData = "Very important Data"
var destFolder = DriveApp.getFoldersByName("Folder"); //create Drive folder if not already created
var destFolder = destFolder.hasNext() ?
destFolder.next() : DriveApp.createFolder("Folder");
var fileName = "Status.txt"; //create txt file in that folder and add data to it
var newFile = destFolder.createFile(fileName,FData);
var url = newFile.getUrl(); //?GIVE THIS URL TO openUrl.html?
var htmlOutput = HtmlService.createHtmlOutputFromFile('openUrl').setHeight(100);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Opening...');
}
HTML (openUrl.html):
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
var urlToOpen = url; //insert grabbed Url here
var winRef = window.open(urlToOpen);
google.script.host.close();
</script>
</head>
<body>
</body>
</html>
In your script, how about the following modification?
Google Apps Script side:
function myFunction() {
var FData = "Very important Data"
var destFolder = DriveApp.getFoldersByName("Folder");
var destFolder = destFolder.hasNext() ? destFolder.next() : DriveApp.createFolder("Folder");
var fileName = "Status.txt";
var newFile = destFolder.createFile(fileName, FData);
var htmlOutput = HtmlService.createTemplateFromFile('openUrl');
htmlOutput.url = newFile.getUrl();
SpreadsheetApp.getUi().showModalDialog(htmlOutput.evaluate().setHeight(100), 'Opening...');
}
HTML & Javascript side:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
var urlToOpen = "<?!= url ?>";
var winRef = window.open(urlToOpen);
google.script.host.close();
</script>
</head>
<body>
</body>
</html>
When myFunction() is run, a dialog is opened by HTML including url using HTML template.
Reference:
HTML Service: Templated HTML

Get Variable Value from inside code.gs Google App Script to Javascript

I have a simple webapp that show a button and when a user clicked, it will open a new window that shows a website. What I want to do is when a user clicked the button, it will get the value from my google sheet and open a new window based on that value. Then, the webapp will update the value in the google sheet with a new value.
For example:
if the value in my google sheet is "Google", it will open a window to "www.google.com" and then update the google sheet value to "other website".
I have succesfully made the function for updating the value on google sheet whenever a user clicked the button but I fail in getting the value from the code.gs/google sheet to my Javascript.
Please help.
here is my code.gs:
var url = "url"; //mygooglesheet url
var web = "";
function doGet(e) {
let tmp = HtmlService.createTemplateFromFile("index");
return tmp.evaluate();
}
function setWebsite () {
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("website");
web = ws.getRange(1,1,1,1).getValue();
if (web === "Google") {
ws.getRange(1,1,1,1).setValue("Youtube");
}
else if (web === "Youtube") {
ws.getRange(1,1,1,1).setValue("Facebook");
}
else {
ws.getRange(1,1,1,1).setValue("Google");
}
}
function getWebsite() {
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("website");
var web = ws.getRange(1,1,1,1).getValue();
return web;
}
my index.html:
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Please Click Below</h1>
<!-- <h2><?=web?>:</h2> -->
<button id = "btn" type="submit" >Open Window</button>
<script>
document.getElementById("btn").addEventListener("click", doStuff);
var web = "";
function doStuff() {
google.script.run.getWebsite(); //dont know for sure if this is needed or not
google.script.run.setWebsite();
web = <?=web?>; //dont know for sure if this is needed or not
if (web === "Google") {
window.open("https://www.google.com/");
}
else if (web === "Youtube") {
window.open("https://www.youtube.com/");
}
else {
window.open("https://www.facebook.com/");
}
}
</script>
</body>
</html>
Right now, my webapp only open a new window to "facebook.com" and update to the next value in the code. I tried "google.script.run.withSuccessHandler(onSuccess).getWebsite()" but not successful to get the variable value from the code.gs, please help.
Thank you.
Issue:
You want to open a new tab with the URL returned by getWebsite() when the button is clicked.
Solution:
In order to handle data returned by a server-side function called by google.script.run, use the success handler. The function called by this handler will be passed the value returned by the server-side function (getWebsite()) as a parameter.
Code sample:
<html>
<head>
<base target="_top">
</head>
<body>
<h1>Please Click Below</h1>
<button id = "btn" type="submit" >Open Window</button>
<script>
document.getElementById("btn").addEventListener("click", doStuff);
function doStuff() {
google.script.run.withSuccessHandler(openWebsite).getWebsite();
}
function openWebsite(web) {
if (web === "Google") {
window.open("https://www.google.com/");
} else if (web === "Youtube") {
window.open("https://www.youtube.com/");
} else {
window.open("https://www.facebook.com/");
}
}
</script>
</body>
</html>
Note:
If the data returned by getWebsite() is supposed to remain static between the moment in which the page first loads and when the button is clicked, you could also use the approach mentioned by Mike Steelson, using template scriplets.
In html, in script section, write
<? var web = getWebsite(); ?>
and erase google.script.run.getWebsite();

Prompt user for range in .gs function, pass array to html script and re-focus on the HTML dialog

I have a google sheet, I want to prompt a user to select ranges to get information from, store that into an array, and then create a chart in an html popup. I have read a bit about the google.script.run functionality, and understand that without the withSuccessHandler(HTMLFunction).FunctionToCall() syntax at the end, the HTML script moves onto the next line. I have a .gs file below, and an .html file, and I was able to get the graph to work when I just entered a static array in my .gs function. However, I seem to be struggling with how to return focus to the editor to get a range, and then to bring the HTML dialog box with the chart back up and get the right data to the function that plots the chart. I saw here that I could use the google.script.host to call the editor.focus() function so the user can now select cells, but I can't seem to get the focus back to the HTML popup without calling the HTML file all over again. Here is my .gs function:
function RetrieveData(){
var ss = SpreadsheetApp.getActive();
var sheets = ss.getSheets();
var s = sheets[1];
var UI = SpreadsheetApp.getUi();
var response = UI.prompt("Please enter the first cell in the category").getResponseText();
var ir = s.getRange(response);
var n= 0;
var stored = [];
stored.push(["Income Category", "Frequency"]);
while (ir.getValue()!= "") {
n = n +1;
ir = ir.offset(1, 0);
}
ir = ir.offset(-n,0)
for(i =0; i<n;i++) {
stored.push([ir.getValue(),ir.offset(n+2,0).getValue()]);
ir = ir.offset(1, 0);
}
return stored;
}
Here is my html that is within the body (Stack Overflow is a little strict, so I am not going to go through the trouble of showing all the HTML; this is just within the body and it is what is communicating with the .gs file):
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(getdata);
function getdata() {
google.script.run.withSuccessHandler(drawChart).RetrieveData();
google.script.host.editor.focus();
}
function drawChart(stored) {
//This apparently shows a log of the object
//console.log(stored);
var data = new google.visualization.arrayToDataTable(stored);
console.log(data);
var options = {'title':'Income',
'width':400,
'height':300,
'is3d':true};
// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
google.script.run.withSuccessHandler(drawChart).RetrieveData();
}
One last thing I tried was to call the
SpreadsheetApp.getUi().showModalDialog(html, "Title") function one more time, but without calling the html file all over again, and creating an endless loop, I don't seem to have a way to do that. Any idea how to accomplish this?
Here's a simple example of picking a range with a modeless dialog. With just a few extra features thrown in for good measure.
Code.gs:
function selRange()//run this to get everything started. A dialog will be displayed that instructs you to select a range.
{
var output=HtmlService.createHtmlOutputFromFile('pickRange').setWidth(300).setHeight(200).setTitle('Select A Range');
SpreadsheetApp.getUi().showModelessDialog(output, 'Range Selector');
}
function selCurRng()
{
var sso=SpreadsheetApp.getActive();
var sh0=sso.getActiveSheet();
var rg0=sh0.getActiveRange();
var rng0A1=rg0.getA1Notation();
rg0.setBackground('#777700');
return rng0A1;
}
function clrRange(range)
{
var sso=SpreadsheetApp.getActive();
var sh0=sso.getActiveSheet();
var rg0=sh0.getRange(range);
rg0.setBackground('#ffffff');
}
pickRange.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var grange='';
function selectRange()
{
$('#btn1').prop('disabled',true);
$('#btn2').prop('disabled',false);
google.script.run
.withSuccessHandler(setResponse)
.selCurRng();
}
function setResponse(r)
{
grange=r;
var msg='You have select the range ' + r;
$('#instr').css('display','none');
$('#rsp').text(msg);
}
function clearAndClose()
{
google.script.run.clrRange(grange);
google.script.host.close();
}
console.log('My Code');
</script>
</head>
<body>
<div id="rsp"></div>
<div id="instr">Please select your desired range.</div>
<input type="button" id="btn1" value="Range Selected" onClick="selectRange();" />
<br /><input type="button" id="btn2" value="close" onClick="clearAndClose();"; disabled="true" />
</body>
</html>

Categories