I've been trying to create a new spreadsheet through google script and google spreadsheet and show it to the user. I could create the sheet with SpreadsheetApp.create; however, I couldn't show it on the browser. When I try to search for it in my drive, it is showing up.
I noticed a method show for Sheet, so, I tried that with a single sheet that I created in the newly created Spreadsheet, however, that is not working.
Using GAS, you can't navigate the user to another spreadsheet programmatically.
What you could do is using this show method and present HTML content with a link to the newly created spreadsheet. They'd obviously have to click the link to proceed.
There might be some other things that we can do, but we'd need to know more context as far as what you're trying to accomplish and why.
Create and Show Spreadsheet From a StandAlone WebApp
You could do something like this with a webapp.
Code.gs:
function createSpreadsheet(name){
var file=SpreadsheetApp.create(name);
var sh=file.getActiveSheet();
var fObj={};
sh.appendRow(['FileName:',file.getName()]);
sh.appendRow(['Url:',file.getUrl()]);
sh.appendRow(['Sheet Name:',file.getSheetName()]);
sh.appendRow(['Id:',file.getId()]);
var hl=Utilities.formatString('<a href="%s" target="_blank" >%s</a>', file.getUrl(), file.getName());
fObj['id']=file.getId();
fObj['hl']=hl;
return fObj;
}
function doGet(){
return HtmlService.createTemplateFromFile('creatandshow').evaluate().setTitle('Create and Show Spreadsheet')
}
function include(filename){
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function getFileFolder(Id){
var ss=SpreadsheetApp.openById(Id);
var sh=ss.getActiveSheet();
var file=DriveApp.getFileById(Id);
var folders=file.getParents();
while(folders.hasNext()){
sh.appendRow(['Parent Folder:',folders.next()]);
}
SpreadsheetApp.flush();
}
script.html:
<script>
<script>
function createSpreadsheet(){
var name=$('#ssName').val();
if(!name) {
alert('You did not enter a Spreadsheet Name');
}else{
google.script.run
.withSuccessHandler(function(fObj){
$('#sslinks').html(fObj.hl);
google.script.run.getFileFolder(fObj.id);
})
.createSpreadsheet(name);
}
}
</script>
resources.html:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
creatandshow.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('resources') ?>
<?!= include('css') ?>
<?!= include('script') ?>
</head>
<body>
<div id="sslinks"></div>
<div id="controls">
<input id="ssName" type="text" placeholder="Enter New Spreadsheet Name" size="60" />
<input id="btn1" type="button" value="Create Spreadsheet" onClick="createSpreadsheet();" />
</div>
</body>
</html>
Here's what it looks like:
Related
I'm working on a project, where the user will use side-bar html page, as a form to update a sheet (very basic operation).
I'm having issue with the autocomplete part.
I'm a beginner to code html with google apps script, so please let me know if you don't have enough information.
The script is supposed to get names from a google sheets, and populate it to the autocomplete item.
I followed a tutorial doing practically the same operation, but based on a web app using a google spreadsheet ==> this one worked perfectly for me.
The challenge is now into adapting it to a sidebar page on google sheet ==> does not work at the moment.
I've been struggling for hours and trying different options, so here is :
- What I made on gs page :
var ss = SpreadsheetApp.getActiveSpreadsheet();
var shEmployees = ss.getSheetByName("Employes");
var colEmploye_nomPrenom=1;
var colEmploye_barcode=colEmploye_nomPrenom+1;
var colEmploye_mail=colEmploye_barcode+1;
var colEmploye_metier=colEmploye_mail+1;
function loadBasicForm(){
var tmp=HtmlService.createTemplateFromFile("basicHtmlForm");
var html = tmp.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
html.setTitle("Test");
SpreadsheetApp.getUi().showSidebar(html);
}//function loadBasicForm(){
function getUnactiveEmployees(){
var ws=shEmployees;
var values= ws.getRange(1,1,ws.getLastRow(),colEmploye_metier).getValues();
var options={};
for (var i=0;i<values.length;i++){
var name=values[i][colEmploye_nomPrenom-1];
var job=values[i][colEmploye_metier-1];
var testUnactive_OK=job=="Désactivé";
if (testUnactive_OK){
options[name]=null;
}//if (testUnactive_OK){
}//for (var i=0;i<values.length;i++){
Logger.log (options);//returns {employee1=null, employee8=null, employee3=null, employee9=null, employee5=null, employee10=null, employee7=null, employee6=null, employee11=null, employee4=null, employee2=null}
return options;
}
What I made on html page :
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"><!--Import Google Icon Font-->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"><!-- Compiled and minified CSS -->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <!--Let browser know website is optimized for mobile-->
</head>
<body>
<div class="container">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">account_circle</i>
<input type="text" id="searchedEmployee" class="autocomplete" required><!-- ISSUE AT FILLING IT -->
<label for="searchedEmployee">Spell a Name</label>
</div>
</div><!-- END ROW -->
</div ><!-- END CONTAINER -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script> <!-- Compiled and minified JavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
google.script.run.withSuccessHandler(populateEmployees).getUnactiveEmployees();
});
function populateEmployees(employees){
var autocomplete = document.getElementById('searchedEmployee');
var instances = M.Autocomplete.init(autocomplete, { data:employees });
}
</script>
</body>
</html>
At this point, the side-page is displayed, but nothing is suggested at typing, for example : "emp" for "employeeX" expected with the "getUnactiveEmployees" list.
EDIT :
My issue is not about displaying - that does displaying.
What I cannot do, is to allow the script to autocomplete the item "searchedEmployee". I guess there is an error on this part :
document.addEventListener('DOMContentLoaded', function() {
google.script.run.withSuccessHandler(populateEmployees).getUnactiveEmployees();
});
Do you have any idea of what I did wrong ?
Many thanks !
Try this:
function loadBasicForm(){
SpreadsheetApp.getUi().showSidebar(HtmlService.createHtmlOutputFromFile('basicHtmlForm').setTitle('Test'));
}
I am using google web app in order to build simply HTML which inserting some informations filled by user to google sheet (apps script application is hosted in a Google Apps Enterprise account). What I'm trying to do is display user e-mail at HTML Page by using Session.getEffectiveUser().getEmail() method. Could you please advise me how can I do it?
This is my code.gs:
function doGet(e) {
return HtmlService.createTemplateFromFile("page.html").evaluate();
}
function userClicked(userInfo){
var url ="path";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("BAZA");
var l_row = ws.getLastRow() + 1
ws.getRange(l_row,1).setValue(userInfo.RANK)
Here is HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<?!= include("page-css.html"); ?>
</head>
<body>
<div class="row">
<div class="input-field col s2">
<select id="RANK">
<option value="" disabled selected>Wybierz rank </option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<label>Rank</label>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<?!= include("page-js.html"); ?>
**HERE SHOULD BE USER ADDRESS EMAIL**
</body>
</html>
JavaScript code:
<script>
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('select');
var instances = M.FormSelect.init(elems);
});
document.getElementById("btn").addEventListener("click",clickedBtn);
function clickedBtn(){
var responseInfo = {};
responseInfo.RANK = document.getElementById("RANK").value;
google.script.run.userClicked(responseInfo);
}
</script>
Since you are using a template (createTemplateFromFile) you could replace
**HERE SHOULD BE USER ADDRESS EMAIL**
by
<?= Session.getEffectiveUser().getEmail() ?>
In order to this to work, you should set to web application to be executed as the user who is accessing it.
Reference
https://developers.google.com/apps-script/guides/web
Session.getEffectiveUser()
I having a problem where I want costumers to sign their signature with a tablet pen and send it in to our sheet but never getting the script. I would love some help to get a script there you can sign a field in google form that will show as a png, or make a web app there you can make a sign that I connected to the sign that will send the e sign to the sheet auto.
There are two things you can do
Simple: Have the users prepare a signature saved as png beforehand and include into your Google Form a "File upload" item
Elegant: Create custom HTML form with a Google Web App and use jSignature
Sample Web App
.gs file
function doGet() {
return HtmlService
.createTemplateFromFile('index')
.evaluate();
}
function saveToDrive(signature){
...
var signature = signature.split(",")
var blob = Utilities.newBlob(Utilities.base64Decode(signature[1]), 'image/png');
var sheet=SpreadsheetApp.getActive().getActiveSheet();
sheet.insertImage(blob, 1, 1);
...
}
index.html file
<!DOCTYPE html>
<html>
<head><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/></head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/willowsystems/jSignature/master/libs/jSignature.min.js"></script>
<body>
<form>
...
Signature:
<div id="signature"></div><br>
<img id="rendered" src="" style="display:none">
<input type="Submit" value="Save" onclick="getSignature();"/>
...
</form>
</body>
<script>
document.getElementById("signature").style.border = "1px solid black";
$("#signature").jSignature({
'background-color': 'transparent',
'decor-color': 'transparent'
});
function getSignature(){
$("img#rendered").attr("src",$('#signature').jSignature('getData','default'));
var signature = document.getElementById('rendered').src;
google.script.run.saveToDrive(signature);
}
</script>
</html>
I'm linking the library with the src attribute and using a function to call it and its not working
GS:
function doGet(e) {
var params = JSON.stringify(e.parameters)
var params2 =JSON.parse(params)
cache.put("name", params2.name)
cache.put("DBID", params2.DBID)
return HtmlService.createTemplateFromFile("test").evaluate()
}
function include(f1){
return HtmlService.createHtmlOutputFromFile(f1).getContent();
}
Html:
<head>
<title>Email form test</title>
<?!= include("CSS") ?>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#8.17.6/dist/sweetalert2.all.js"></script>
<?!= include('Javascript') ?>
<button type="button" name="Submit" onclick="javascript:t1();"id="sub1"class="btn btn-white btn-animation-1">Submit</button>
Calling library (after its been initialized above):
<script>
function t1(){
Swal.fire('Any fool can use a computer');
}
</script>
the expected result should be I click the button and "any fool can use a computer" should pop up in a sweet alert 2 box
You don't need to import and evaluate the Sweetalert library within Apps Script - you can include it in your HTML file as you would normally and return the HTML Output from file on doGet():
code.gs:
function doGet(e) {
// your code here
return HtmlService.createHtmlOutputFromFile("index");
}
and index.html:
<!DOCTYPE html>
<html>
<head>
<title>Email form test</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#8.17.6/dist/sweetalert2.all.js"></script>
<button type="button" name="Submit" onclick="t1();"id="sub1"class="btn btn-white btn-animation-1">Submit</button>
<script>
function t1(){
Swal.fire('Any fool can use a computer');
}
</script>
</body>
</html>
Reference :
Single Google Form for multiple Sheets
Re-claim :
I have a little bit hard to made my writing some good or as well to
be understanding (less english).
I have a little insight about a Google Apps Script (GAS).
I have change "MyURLDoc" and "MyIdDoc" bellow as cosinderring of
mine.
Question :
How do I make a Google Form be inside of a Pop up what I've made in Google Spreadsheet ?
Attempt 1 :
function goToURL() {
FormApp.openByUrl(//*** MyURLDoc! ***//);
}
Attempt 2 :
Following as the reference has worte there!
function goToForm() {
var form = FormApp.openById(//*** MyIdDoc! ***//),
formUrl = form.getPublishedUrl(),
response = UrlFetchApp.fetch(formUrl),
formHtml = response.getContentText(),
htmlApp = HtmlService
.createHtmlOutput(formHtml)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('Ta Daaa!')
.setWidth(500)
.setHeight(450); SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
}
Problem :
It says always like this: " No item with the given ID could be found or You do not have permission "
Creating a Sidebar with a Google Form
I just went to an old form I have and got the embed code. I loaded into a sidebar that I had on another project and pasted the embed code which is an iframe and it loaded perfectly except for the size and I ran the form and sure enough it loaded data into the spreadsheet that contains it.
I thought I'd go ahead and add a complete example. This is a simple example which creates a form for inputting time stamped text into a spreadsheet. It's done two ways. The first technique uses standard html, javascript, JQuery and Google Script. The second technique is accomplished by just creating a form and embedding it into a simple html page. Both versions fit into the side bar and both are linked to spreadsheet pages where the text is loaded and timestamped.
Code.gs:
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('createTextEntryForm', 'createTextEntryForm')
.addToUi();
loadSideBar();
SpreadsheetApp.getUi().createMenu('My Menu').addItem('loadSidebar', 'loadSideBar').addToUi();
}
//This loads the text into the spreadsheet for the html version of the form.
function dispText(txt)
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sht=ss.getSheetByName('Notes');
var ts=Utilities.formatDate(new Date(), 'GMT-6', "M/dd/yyyy HH:mm:ss");
var row=[];
row.push(ts);
row.push(txt);
sht.appendRow(row);
return true;
}
function loadSideBar()
{
var userInterface=HtmlService.createHtmlOutputFromFile('formBar');//sidebar for html and formBar for form
SpreadsheetApp.getUi().showSidebar(userInterface);
}
//This is the form
function createTextEntryForm()
{
var ss=SpreadsheetApp.getActiveSpreadsheet();
var form=FormApp.create('Form On A Sidebar');
form.setDescription('Enter Your Message and Push Submit when complete.')
.setConfirmationMessage('Message Saved and TimeStamped.')
.setAllowResponseEdits(true)
.setAcceptingResponses(false)
.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
var containerLink=form.addParagraphTextItem();
containerLink.setTitle('Enter your comment now.')
.isRequired();
}
sidebar.html which is the html version of the form:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
$('#txt1').val('');
});
function sendText()
{
var txt=$('#txt1').val();
google.script.run
.withSuccessHandler(clearText)
.dispText(txt);
}
function clearText()
{
$('#txt1').val('');
}
console.log("My code");
</script>
</head>
<body>
<textarea id="txt1" rows="12" cols="35"></textarea>
<br />
<input id="btn1" type="button" value="submit" onClick="sendText();" />
</body>
</html>
formBar.html is where the form is embedded:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<iframe src="FormURL?embedded=true#start=embed" width="300" height="550" frameborder="0" marginheight="0" marginwidth="0">Loading...</iframe>
</body>
</html>
This is what the spreadsheet and sidebars look like: