Move sheet when drop-down menu is selected - javascript

I want to implement a function that moves to the selected sheet when selecting the drop-down menu (sheet name) in Google spreadsheet, but it's not working well.
The menu shows all the seat names, but if you select that particular seat, nothing will happen.
I keep searching and searching, but I don't see a clear solution. What should I do? Please help me.
The code I wrote is as follows.
code.gs
function onOpen() {
createMenu()
}
function createMenu(){
const ui = SpreadsheetApp.getUi()
const menu = ui.createMenu("Sidebar")
menu.addItem("Open Sidebar", "openSidebar");
menu.addToUi()
}
function openSidebar() {
ss = SpreadsheetApp.getActiveSpreadsheet();
var html = HtmlService.createTemplateFromFile('sidebar')
.evaluate()
.setTitle('Salesforce')
.setWidth(400);
SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
.showSidebar(html);
}
sidebar.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button id = "moveButton" class="button alert">Move</button>
<select name="Available sheets" onchange="moveSheet()" style="width:280px;height:30px;">
<? var sheets=ss.getSheets(); ?>
<? for(var i=0;i<sheets.length;i++) { ?>
<option value=<?=sheets[i].getName()?>> <?= sheets[i].getName()?></option>
<? } ?>
</select>
<script>
function myJsFunction(){
var name = document.getElementsByName("Available sheets")[0].value;
}
function moveSheet(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(name);
if(sheet !=null){
ss.moveActiveSheet(sheet);
}else{
//
}
}
document.getElementById("moveButton").addEventListener("click",moveSheet());
//google.script.run.withSuccessHandler(name);
};
</script>
</body>
</html>

I believe your goal is as follows.
You want to move the sheet by selecting the sheet name from the dropdown list at the sidebar of Spreadsheet.
When I saw your showing script, I thought that you are trying to run the Google Apps Script at the sidebar. At the sidebar and dialog of Spreadsheet, the Javascript is run with the client browser. On the other hand, Google Apps Script is run on the internal server side of Google. I thought that this might be the reason for your issue.
When your showing script is modified for achieving your goal, how about the following modification?
Google Apps Script side: code.gs
In this modification, your function of openSidebar is modified and a new function of moveSheet is added.
Here, in order to move the active sheet, activate() is used.
function moveSheet(e) {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName(e).activate();
}
function openSidebar() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var options = ss.getSheets().map(s => {
var sheetName = s.getSheetName();
return `<option value="${sheetName}">${sheetName}</option>`;
}).join("");
var html = HtmlService.createTemplateFromFile('sidebar');
html.options = options;
var h = html.evaluate().setTitle('Salesforce').setWidth(400);
SpreadsheetApp.getUi().showSidebar(h);
}
HTML side: sidebar.html
I modified select tag and removed moveSheet().
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button id="moveButton" class="button alert">Move</button>
<select name="Available sheets" onchange="google.script.run.moveSheet(this.value)" style="width:280px;height:30px;">
<?!= options ?>
</select>
<script>
document.getElementById("moveButton").addEventListener("click",moveSheet());
//google.script.run.withSuccessHandler(name);
};
</script>
</body>
</html>
When you run openSidebar, a sidebar is opened. And, you can see the dropdown list including the sheet names. When you change the dropdown list, the active sheet is changed to the sheet of the selected sheet name.
References:
HTML Service: Templated HTML
activate()

Related

Text input value does not display on page load until select option is changed

I am trying to load options into a select box from a Google Sheet. My code currently almost works, however, the initial select option is not loading the corresponding value into the text input box when the page first displays. When the select box option is changed, the value is properly loaded into the text box. How can I load both the option and value on the initial page load?
Code.gs
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu("Sidebar")
.addItem("Show sidebar", "showSidebar")
.addToUi();
}
function showSidebar() {
var htmlWidget = HtmlService.createHtmlOutputFromFile('Test')
SpreadsheetApp.getUi().showSidebar(htmlWidget);
}
function getList() {
var items = SpreadsheetApp.getActive().getRange("Sheet1!A1:B3").getValues();
return items;
}
Test.html
<!DOCTYPE html>
<html>
<script>
function loadSelectBox() {
google.script.run.withSuccessHandler(function(ar)
{
var itemList = document.getElementById("itemSelectBox");
ar.forEach(function(item, index)
{
var option = document.createElement("option");
option.value = item[1];
option.text = item[0];
itemList.appendChild(option);
});
}).getList();
getPath();
}
function getPath()
{
var path = document.getElementById("itemSelectBox").value;
document.getElementById("itemPath").value = path;
}
</script>
<head>
<base target="_top">
</head>
<body>
<select id="itemSelectBox" onchange="getPath()" style="width: 60%"></select>
<br>
<input type="text" id="itemPath" style="width: 60%">
<script>
loadSelectBox();
</script>
</body>
</html>
In your script, how about the following modification?
Modified script:
Please modify loadSelectBox() as follows.
function loadSelectBox() {
google.script.run.withSuccessHandler(function (ar) {
var itemList = document.getElementById("itemSelectBox");
ar.forEach(function (item, index) {
var option = document.createElement("option");
option.value = item[1];
option.text = item[0];
itemList.appendChild(option);
});
getPath(); // <--- Modified
}).getList();
}
In your showing script, getPath(); is put outside of google.script.run. google.script.run is run with the asynchronous process. By this, before withSuccessHandler is run, getPath() is run. I thought that this is the reason for your issue.
Reference:
Class google.script.run (Client-side API)
I think the problem is that you have the javascript in the header and thus it's run before the dom (html) is created.
You can
a) move your javascript into a in the end
b) trigger your code once https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event is fired.
alternative a might work better but it's not pretty to have html and JS mixed unless you really have to.

Google apps script html to spreadsheet

I am learning google apps script at the moment by myself.
I have been trying to get someone's mail and append it to a google spreadsheets.
My code.gs looks actually like this:
function doGet() {
return HtmlService.createHtmlOutputFromFile("page");
};
function addEmail (mail) {
var mysheet = SpreadsheetApp.openById("1k3vWmg9859mYykNNl0xDWoR_LUhnvLlq1qW8kSRuL_Q").getSheetByName("Sheeet1");
mysheet.appendRow(mail);
};
And my html file looks like this:
<html>
<head>
<base target="_top">
</head>
<body>
<h1>hello</h1>
</body>
<label for="getUserMail">Type your mail here</label> <input type="text" id="getUserMail">
<button id="trigger">Submit!</button>
<script>
document.getElementById("trigger").addEventListener("click",sendMailToCode);
function sendMailToCode () {
var umail = document.getElementById("getUserMail");
google.script.run.addEmail(umail);
};
</script>
</html>
But it doesn't work. I have tried doing multiple stuff to fix it, even adding a tag on html but it does not save the value on the spreadsheet. Could someone please give an advice?
Try this:
This will append the html to the sheet but it will not render it.
function addEmail (mail='<html><head><basetarget="_top"></head><body><h1>hello</h1></body><labelfor="getUserMail">Typeyourmailhere</label><inputtype="text"id="getUserMail"><buttonid="trigger">Submit!</button><script>document.getElementById("trigger").addEventListener("click",sendMailToCode);functionsendMailToCode(){varumail=document.getElementById("getUserMail");google.script.run.addEmail(umail);};</script></html>') {
var ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
sh.appendRow([mail]);
}
appendRow
Reading the description of row contents: "An array of values to insert after the last row in the sheet."

Updating or inserting data from a Spreadsheet into a Dialog box inside a dropdown

Goal: The purpose is that a sheet will contain information, this information is placed inside a namedrange, the namedrange will be dynamic (the entire column is given a namedrange).
I created a html popup which contains a dropdown list. This dropdown list must contain the list of information from the namedrange.
I am unable to understand how this is to be done. Here is the code below:
function fncOpenMyDialog() {
var htmlDlg = HtmlService.createHtmlOutputFromFile('HTML_myHtml')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(200)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'New File');
};
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('New')
.addItem('New Save File Extension','fncOpenMyDialog')
.addToUi();
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select name="nameYouWant" placeholde="File Type">
<option value="something">Word</option>
<option value="anything">MS Excel</option>
<option value="anything">MS Powerpoint</option>
<option value="anything">MS Slides</option>
</select>
<hr/>
<p>Choose a file, which will then be saved into your Google Drive.</p>
<button onmouseup="closeDia()">Close</button>
<button onmouseup="onOpen()">Save</button>
<script>
window.closeDia = function() {
google.script.host.close();
};
window.saveDia = function() {
onOpen();
};
</script>
</body>
</html>
As you can see in my html file, that the extensions are currently hardcoded.
I am trying to make this dynamic, how do I achieve this?
I believe your goal as follows.
You want to put the values to the dropdown list by retrieving from the named range of the Spreadsheet.
In this case, is the named range the same with this thread?
For this, how about this answer?
Modification points:
From google.script.host.close(), I understood that the HTML file of HTML_myHtml is included in the Google Apps Script project. By this, I would like to propose to achieve your goal using google.script.run.
If the named range is the same with your previous question, you can use it by modifying a little.
When above points are reflected to your script, it becomes as follows.
Modified script:
HTML and JavaScript side: HTML_myHtml
Please modify HTML_myHtml as follows.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select id="select" name="nameYouWant" placeholde="File Type"></select>
<hr />
<p>Choose a file, which will then be saved into your Google Drive.</p>
<button onmouseup="closeDia()">Close</button>
<button onmouseup="onOpen()">Save</button>
<script>
google.script.run.withSuccessHandler(v => {
const obj = document.getElementById("select");
v.forEach(e => {
const option = document.createElement("option");
option.text = e;
option.value = e;
obj.appendChild(option);
});
}).readNamedRange();
window.closeDia = function() {
google.script.host.close();
};
window.saveDia = function() {
onOpen();
};
</script>
</body>
</html>
Google Apps Script side: Code.gs
At above HTML, readNamedRange() is used. So please put the following script. If you have the same function names, please modify them. In this script, the values are retrieved from the named range of listDown, and sent to HTML side using google.script.run.
function readNamedRange() {
var activeSheet = SpreadsheetApp.getActiveSheet();
var result = activeSheet.getRange("listDown").getValues();
var end = activeSheet.getLastRow();
var values = [];
for (var i = 0; i < end; i++) {
if (result[i][0] != "") {
values.push(result[i][0]);
}
}
return values;
}
Note:
About window.saveDia = function() {onOpen()};, unfortunately, I couldn't understand about what you want to do.
Reference:
Class google.script.run

Working tested javascript doesn't work when running from Google Sheets html template

I'm very very new to scripting in general, so please bear with me.
I am testing some scripts on google sheets, running an HTML template.
Part of my script requires calling on array data. I am testing running this script: http://jsfiddle.net/nExgJ/
You will see that the script runs as desired.
However, when the HTML template launches from Google Sheets, even with the same code, the numbers are not populated.
In Google Sheets script, the following function is used to run the HTML template:
var htmlDlg = HtmlService.createHtmlOutputFromFile('index')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(500)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'Select An Existing Client');
}
I also have a doGet function in place, which is as follows:
function doGet() {
var htmlOutput = template.evaluate()
.setSandboxMode(HtmlService.SandboxMode.NATIVE);
return htmlOutput;
return HtmlService.createHtmlOutputFromFile('index');
}
Then the code in my HTML form is as follows:
<!DOCTYPE html>
<html>
<head>
<script>
// Get dropdown element from DOM
var dropdown = document.getElementById("selectNumber");
// Loop through the array
for (var i = 0; i < myArray.length; ++i) {
// Append the element to the end of Array list
dropdown[dropdown.length] = new Option(myArray[i], myArray[i]);
}
</script>
</head>
<body>
<form id="myForm">
<select id="selectNumber">
<option>Choose a number</option>
</select>
</form>
</body>
</html>
the actual result when code is run
Any help would be greatly appreciated. Thanks!
In Apps Script you can implement this functionality by using scriptlets
The advantage of scriptlets is that you can also incorporate data from your spreadsheet or variables from Code.gs into your options.
Sample:
index.html
<!DOCTYPE html>
<html>
<head>
<script>
</script>
</head>
<body>
<form id="myForm">
<select id="selectNumber">
<option>Choose a number</option>
<? var myArray = new Array("1", "2", "3", "4", "5");?>
<? for (var i = 0; i < myArray.length; ++i) { ?>
<option> <?=myArray[i]?> </option>
<? } ?>
</select>
</form>
</body>
</html>
Code.gs
function myFunction() {
var template = HtmlService.createTemplateFromFile('index');
var htmlDlg = template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(500)
.setHeight(150);
SpreadsheetApp.getUi()
.showModalDialog(htmlDlg, 'Select An Existing Client');
}
UPDATE:
If you prefer to use your script, you have to move it from head to body, after the rest of your html content.
This allows you to render the HTML content (basically create a element with the id "selectNumber") before you modify the contents of this html with Javascript, see Best Practices.

Google Apps Script - return output from apps script function back to the html file javascript function

Ok, so I am trying to make a function in google sheets that when the user selects a cell and then runs the function (currently trying to make), a sidebar getting all the synonyms of the word should appear. I am using https://words.bighugelabs.com/ to get the synonyms. So first I make the menu:
`function onOpen(e) {
var ui = SpreadsheetApp.getUi().createMenu("Sidebar")
.addItem("Get Synonym", 'showSidebar')
.addToUi();
}`
Then this is the showSidebar function:
function showSidebar() {
var html = HtmlService.createHtmlOutputFromFile("Test")
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(150)
.setTitle("My Sidebar");
SpreadsheetApp.getUi().showSidebar(html);
}
This is the html file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function doSomething() {
var synonyms = google.script.run.getSynonym();
document.getElementById("synonyms").innerHTML = synonyms;
}
</script>
</head>
<body>
<div>
<span style="color:orange;">This is a test sidebar!</span>
<button onclick="doSomething()">Click Me!</button>
<div id="synonyms"></div>
</div>
</body>
</html>
And this is the getSynonym function:
function getSynonym() {
var word = SpreadsheetApp.getActiveRange().getValue();
var synonyms = [];
var response = UrlFetchApp.fetch("http://words.bighugelabs.com/api/2/{my_api_key}/" + word + "/json");
response = JSON.parse(response);
var synonyms = response.adjective.syn;
return synonyms;
}
But the variable synonyms which as an array of synonyms doesn't get returned to the doSomething function in the Html file.
What I want is that the sidebar should get a list of all the synonyms.
So basically I can't get the data from one function to another...and I want to know if this is the right way.
When calling server side functions using google.script.run you need to define a success handler, which will asynchronously receive your response.
See the examples on: https://developers.google.com/apps-script/guides/html/communication
function onSuccess(synonyms ) {
console.log(synonyms);
}
google.script.run.withSuccessHandler(onSuccess).doSomething();

Categories

Resources