How to implement DatePicker in my Google Apps Scripts - html

I would like to make the two dates start_date_cal and end_date_cal chosen by the user who is running the script below.
By reading a lot about how to do that, I have found plenty about Html Services, but I couldn't successed in implementing it in my code.
function main_cotisations() {
var cell_col_number = "";
var cell_row_number = "";
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('2019-2020');
//ss.setActiveSelection('A3');
ss.getRange('A3').activate();
// Get active cell and get value of it
var cell = ss.getCurrentCell();
var cellValue = cell.getValue();
var start_date_cal = new Date('December 12, 2019 19:00:00 +1100');
var end_date_cal = new Date('December 12, 2019 22:30:00 +1100');
// Start the loop
while (cellValue != ""){
cellValue = cell.getValue();
if (cellValue != "") {
var infos_user = {};
infos_user.prenom = sheet.getRange(cell.getRow(),cell.getColumn()+2).getValue();
infos_user.mail = sheet.getRange(cell.getRow(),cell.getColumn()+3).getValue();
infos_user.solde_a_payer = sheet.getRange(cell.getRow(),cell.getColumn()+8).getValue();
infos_user.url_calendar = 'https://www.google.com/calendar/render?action=TEMPLATE&text=Penser+aux+capitations+: '+infos_user.solde_a_payer+'F&location=Ducos&dates='+getRelativeDate(start_date_cal)+'%2F'+getRelativeDate(end_date_cal);
if (sheet.getRange(cell.getRow(),cell.getColumn()+9).isChecked() == false) {
sendmail_paiement(infos_user);
}
};
cell = cell.offset(1, 0);
};
var infos_globales = {};
infos_globales.solde_global = sheet.getRange(cell.getRow()-1,cell.getColumn()+8).getValue();
infos_globales.nb_user_hospitalier = sheet.getRange(cell.getRow()-1,cell.getColumn()+9).getValue();
infos_globales.nb_user_retard =sheet.getRange(cell.getRow()-1,cell.getColumn()+10).getValue();
}
//***********************************************************************************************************************
function getRelativeDate(given_date) {
//{given_date = Utilities.formatDate(temp_date, "GMT", "yyyyMMdd'T'HHmmss'Z'");}
temp = Utilities.formatDate(given_date, "GMT", "yyyyMMdd'T'HHmmss'Z'");
return temp.toString();
}
function sendmail_paiement(infos_user) {
var templ = HtmlService
.createTemplateFromFile('tpl_mail_exceptionnel');
templ.infos_user = infos_user;
var message = templ.evaluate().getContent();
if (infos_user.solde_a_payer>0) {
MailApp.sendEmail(
infos_user.mail,
"Rappel de capitations",
'',
{htmlBody: message,}
);
}
}
I would appreciate some help here.

It could be implemented by developing an WebApp from there you could create a form with a date picker and a submit button to send the date back to the apps script and execute your code.
I've done a little demo:
Go apps script and make a new project:
function doPost(e) {
Logger.log(e.parameter.start);
Logger.log(e.parameter.end);
return HtmlService.createHtmlOutput("Hi there, <br> When you click submit doPost() function is called. <br> By calling e.parameter.start you'll get the desired dates <br> Like:" +e.parameter.start+ "<br>Now check the logs. <br> Good luck");
}
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('index');
}
Now, on apps script, press File --> New --> Html file --> Name it 'index'
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form action="PASTE_YOUR_WEBAPP_LINK_HERE" method="post">
<label for="start">Start date:</label>
<input type="date" id="start" name="start"
value="2019-10-21"
min="2019-01-01" max="2020-12-31">
<input type="date" id="end" name="end"
value="2019-10-22"
min="2019-01-01" max="2020-12-31">
<input type="submit" value="Submit">
</form>
</body>
</html>
Go to Publish --> Deploy as Web App
Copy the link and post it inside the index HTML file, were it says PASTE_YOUR_WEBAPP_LINK_HERE
Now you can visit your deployed WebApp:
Anytime you click submit you'll call doPost() function.
So, now you can paste your code inside doPost() function, you can use the dates from the datepicker and execute any apps script you wish.
Hope this helps.

Related

Create a searching form with 2 input from google sheet database and show result below the form

I am a student who learn to code Apps Script. I want to create a form with 2 number input, let say A & B, with a button. When user submit the form, the script will search column A & B in active Google Spreadsheet sheet that match with 2 input and query a result in the column C on the same row. Finally, the result C will appear below the form.
The problem is that, when the form appear, I input 2 values but the result don't work.
I wrote two file code like this in Apps Script:
The HTML file
<form onsubmit="handleFormSubmit(event)">
<label for="inputA">height:</label><br>
<input type="number" id="inputA" name="inputA"><br>
<label for="inputB">weight:</label><br>
<input type="number" id="inputB" name="inputB"><br>
<input type="submit" value="Submit">
</form><br>
<script>
function handleFormSubmit(event) {
// Prevent the form from refreshing the page
event.preventDefault();
// Get the input values from the form
var inputA = document.getElementById("inputA").value;
var inputB = document.getElementById("inputB").value;
// Search the Google Sheet for a matching row
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var result = "";
for (var i = 0; i < data.length; i++) {
if (data[i][0] == inputA && data[i][1] == inputB) {
result = data[i][2];
break;
}
}
// Display the result on the page
var resultContainer = document.getElementById("result");
resultContainer.innerHTML = result;
}
</script>
<label for="resultA">result is:</label><div id="result"></div>
<!-- Result will be added here -->
The script file:
function doGet(e) {
return HtmlService.createTemplateFromFile('searchForm.html')
.evaluate();
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
The sheet link is here: https://docs.google.com/spreadsheets/d/1DqjBbU4b0uDTtjYsBFVFDuvA9fthR1N3KUCtkvwRowc/edit?usp=sharing
I think the problem is the code in script tag but I don't quite sure.
Modification points:
In your script, it seems that you are using Google Apps Script in the Javascript on the HTML side. Google Apps Script can be used on the server side. So, in this case, google.script.run is used.
When these points are reflected in your script, how about the following modification?
Modified script: searchForm.html
HTML & Javascript:
<form>
<label for="inputA">Input A:</label><br>
<input type="number" id="inputA" name="inputA"><br>
<label for="inputB">Input B:</label><br>
<input type="number" id="inputB" name="inputB"><br>
<input type="submit" value="Submit" onclick="handleFormSubmit(event)">
</form>
<div id="result">
</div>
<script>
function handleFormSubmit(event) {
event.preventDefault();
var inputA = document.getElementById("inputA").value;
var inputB = document.getElementById("inputB").value;
google.script.run.withSuccessHandler(result => {
var resultContainer = document.getElementById("result");
resultContainer.innerHTML = result;
}).sample(inputA, inputB);
}
</script>
Google Apps Script: code.gs
function doGet(e) {
return HtmlService.createTemplateFromFile('searchForm.html').evaluate();
}
function sample(inputA, inputB) {
var sheet = SpreadsheetApp.getActiveSheet(); // or var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var data = sheet.getDataRange().getValues();
var result = "";
for (var i = 0; i < data.length; i++) {
if (data[i][0] == inputA && data[i][1] == inputB) {
result = data[i][2];
break;
}
}
return result;
}
Note:
As an important point of this modification, google.script.run is run with the asynchronous process. Please be careful about this.
When you modified the Google Apps Script of Web Apps, please modify the deployment as a new version. By this, the modified script is reflected in Web Apps. Please be careful about this.
You can see the detail of this in my report "Redeploying Web Apps without Changing URL of Web Apps for new IDE (Author: me)".
Thit is a sample modification. So, please modify this for your actual situation. If you want to know about google.script.run more, you can also see various sample scripts at Stackoverflow.
Reference:
Class google.script.run (Client-side API)

How can I create a web app where I can read text from a sheet based on dropdown selections?

I am trying to create a role description generator which reads pre-written text from a Google Sheet and assembles it in blocks in a web app through selections (team, role, seniority level, etc.) in dropdown menus.
This is an example of what the data in the sheet looks like:
Team name
Team description
A-team
Description
B-team
Description
...
...
So far, for the team selection, I have created the dropdown menu which reads the data from the sheet, and pulls the names of each team into a dropdown list. But my problem is loading the corresponding team description text into the HTML page. I just can't seem to get it to work.
When pressing the generate button, what should happen is that the description for A-team is loaded, but instead I get [object MouseEvent].
Any suggestions? Thanks in advance! :)
Here's my code:
Code.gs
var url = "*spreadsheet URL*";
function doGet(e) {
return HtmlService.createTemplateFromFile('index')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
//get the data for the dropdown list
function valuesForList(list) {
//define the data
var ss = SpreadsheetApp.openByUrl(url)
var teamsSheet = ss.getSheetByName('Data');
var lastRow = teamsSheet.getLastRow();
var teamsRange = teamsSheet.getRange(1, 3, lastRow, 1);
//create a named range
ss.setNamedRange('teamsList', teamsRange);
//get the values from the range
var listValues = ss.getRangeByName(list).getValues();
return listValues;
}
//the function to show the data on the index.html
function PostInfo (userInfo){
//load the data
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Teams");
var data = ws.getRange(2,1,ws2.getLastRow(),2).getValues();
var teamList = data.map(function(r){ return r[0]});
var teamDesc = data.map(function(r){ return r[1]});
var position = teamList.indexOf(userInfo.teams);
if(position > -1){
return teamDesc[position];
} else {
return "Unavailable";
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
<script>
function onListSuccess(list) {
var listLength = list.length;
for (i=0; i<listLength;i++) {
var dropdown = document.getElementById("teams");
var opt = document.createElement("option");
dropdown.options.add(opt);
opt.text = list[i][0];
opt.value = list[i][0];
}
}
function onListSelect(teamDesc){
var text = teamDesc.toString().split(",");
document.getElementById('est').innerHTML = text;
}
</script>
</head>
<body>
<div id="main">
<h1>Role Description Generator</h1>
<p>
<label for="teams">Team:</label>
</p>
<p>
<select name="teams" id="teams" tabindex="2"></select>
</p>
<button id="btn">Generate</button>
<div>
<label for="est">Team description:</label>
<p id="est" name="est"></p>
</div>
</div>
</body>
<script>
function populateList(){
google.script.run.withSuccessHandler(onListSuccess).valuesForList('teamsList');
}
document.getElementById("teams").addEventListener("change", doStuff);
document.getElementById("btn").addEventListener("click", onListSelect);
function doStuff(){
var userInfo = {};
userInfo.teams = document.getElementById("teams").value;
google.script.run.PostInfo(userInfo);
}
window.addEventListener('load', populateList);
</script>
</html>
Modification points:
In your script, when the dropdown list is changed, doStuff() is run. But in this case, google.script.run.PostInfo(userInfo) runs only the function of PostInfo at Google Apps Script. By this, the returned value is not used.
And, when the button is clicked, onListSelect is run. But in this case, teamDesc of onListSelect(teamDesc) is the event object. By this, such value of [object MouseEvent] is shown. I thought that this might be the reason of your issue.
By the way, when I saw your Google Apps Script, I noticed that PostInfo has a modification point. When var data = ws.getRange(2,1,ws2.getLastRow(),2).getValues(); is run, I think that an error occurs. Because ws2 is not declared. In your case, is that ws? I thought that this might be due to your miscopy.
When you want to show the value from PostInfo when the button is clicked, how about the following modification?
Modified script:
HTML&Javascript side:
From:
document.getElementById("teams").addEventListener("change", doStuff);
document.getElementById("btn").addEventListener("click", onListSelect);
function doStuff(){
var userInfo = {};
userInfo.teams = document.getElementById("teams").value;
google.script.run.PostInfo(userInfo);
}
To:
document.getElementById("btn").addEventListener("click", doStuff);
function doStuff(){
var userInfo = {};
userInfo.teams = document.getElementById("teams").value;
google.script.run.withSuccessHandler(onListSelect).PostInfo(userInfo);
}
Google Apps Script side:
From:
var ws = ss.getSheetByName("Teams");
var data = ws.getRange(2,1,ws2.getLastRow(),2).getValues();
To:
var ws = ss.getSheetByName("Teams");
var data = ws.getRange(2,1,ws.getLastRow(),2).getValues();
Note:
In this modidication, it supposes that the Google Apps Script works fine and returns the correct values. Please be careful this.
Reference:
Class google.script.run

Only the else condition works in my google apps script Twilio Fax sending web app

I'm having an issue with my If statement.
Basically I set up a fax app with Twilio and Google apps script.
I give the user a choice to upload a document or send out one that stored on my Google drive.
If I upload a file it works. But if I check the checkbox to send a pre-set document, which I'm trying to accomplish by using the If statement it doesn't send.
I troubleshooted, and found that the If statements is getting a TRUE and FALSE value.
I think the problem is that when there is no file passed into the function it doesn't work. The thing is I'm avoiding the file by the If statement so why is it not working.
Below is my HTML file and server side apps script.
Any suggestions?
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(blob, name, number, test) {
//get destination number
var num = number;
var prefix = "+1";
var removeDashes = num.replace(/-/g,"");
var fullNumber = prefix + removeDashes;
var output;
if (test){
output = "APPLICATION SENT!";
}else{
output = "FAX SENT!";
}
var url;
if (test) {
var appl = DriveApp.getFileById('xxxxxxxxx');
var appurl = appl.getDownloadUrl();
url = appurl;
} else {
var folder = DriveApp.getFolderById('xxxxxxxxxxx');
var blob = blob.split(",");
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'application/pdf');
var fileName = blob.setName(name).getName();
var file = folder.createFile(blob);
//allow access to Twilio
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
//get file url
var id = file.getId();
var getfile = DriveApp.getFileById(id);
var getnewurl = getfile.getDownloadUrl();
var url = getnewurl;
}
//send fax
var faxUrl = "https://fax.twilio.com/v1/Faxes";
var payload = {
"From" : "+1888888888",
"To": fullNumber,
"MediaUrl" : url,
"Method" : "POST",
};
var options = {
"method" : "post",
"payload" : payload
};
options.headers = {
"Authorization" : "Basic " + Utilities.base64Encode("ACxxxxxxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxx")
};
UrlFetchApp.fetch(faxUrl, options);
return "succes" + output;
}
Here is the HTML file: (I removed the <style> in order to shorten)
<!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 upload() {
var file = document.getElementsByName('myFile')[0].files[0];
var number = document.getElementsByName('Pnumber')[0].value;
var test = document.getElementsByName("entered")[0].checked;
var reader = new FileReader();
reader.onload = function (e) {
var content = reader.result;
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(content, file.name, number, test);
return false;
}
reader.readAsDataURL(file);
}
function fileUploaded(status) {
document.getElementById("myForm").reset();
document.getElementById('output').innerHTML = status;
}
</script>
</head>
<body>
<div align="center">
<h1 align="center" style="color:darkblue">FAX APP</h1>
<h2 align="center">SEND OUTGOING FAX</h2>
<hr>
<form id="myForm" align="center">
<label for="pdf">Choose a PDF file to upload -- <b>OR</b>-- Check "SEND APPLICATION" </label>
<br>
<input id="pdf" type="file" name="myFile" >
<br><br>
<input type="checkbox" style="width:25px ; height:25px" name="entered">
<label for="entered" style="font-size:30px" > SEND APPLICATION</label>
<br><br>
<label for="phonenumber">Enter Destination Number</label>
<br>
<input id="phonenumber" type="text" name="Pnumber" placeholder="Phone Number" >
<br>
<input type="submit" value="SEND FAX" onclick="upload()" >
</form>
<p><b>FAX DELIVERY STATUS:</b></p>
<div id="output"align="center"><b></b></div>
<br>
<a href="https://drive.google.com/drive/folders/xxxxxxxxxxxxxxxxxxx?usp=sharing"
target="_blank">SENT FAX DOCUMENTS</a>
</div>
</body>
</html>
BELOW IS THE NOW WORKING CODE OF GOOGLE SCRIPT SIDE AND HTML
THANKS TO #Tanaike's HELP
CURRENT GOOGLE SCRIPT SIDE CODE:
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(blob, name, number, test) {
//get destination number
var num = number;
var prefix = "+1";
var removeDashes = num.replace(/-/g,"");
var fullNumber = prefix + removeDashes;
var output;
if (test){
output = "APPLICATION SENT!";
}else{
output = "FAX SENT!";
}
var url;
if (test) {
var appl = DriveApp.getFileById('xxxxxxxxxxxxxxxxxxxxxxx');
var appurl = appl.getDownloadUrl();
url = appurl;
} else {
var folder = DriveApp.getFolderById('xxxxxxxxxxxxxxxxxxxxxxxxxxx');
var blob = blob.split(",");
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'application/pdf', name);
var file = folder.createFile(blob);
//allow access to Twilio
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
//get file url
var id = file.getId();
var getfile = DriveApp.getFileById(id);
var getnewurl = getfile.getDownloadUrl();
url = getnewurl;
}
//send fax
var faxUrl = "https://fax.twilio.com/v1/Faxes";
var payload = {
"From" : "+188888888888",
"To": fullNumber,
"MediaUrl" : url,
"Method" : "POST",
};
var options = {
"method" : "post",
"payload" : payload
};
options.headers = {
"Authorization" : "Basic " + Utilities.base64Encode("ACxxxxxxxxxxxxxxxxxx:xxxxxxxxxxxxxxxxxxx")
};
UrlFetchApp.fetch(faxUrl, options);
return "Success - " + output;
}
CURRENT HTML SIDE CODE:
<!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 upload() {
var file = document.getElementsByName('myFile')[0].files[0];
var number = document.getElementsByName('Pnumber')[0].value;
var test = document.getElementsByName("entered")[0].checked;
if(!test){
var reader = new FileReader();
reader.onload = function (e) {
var content = reader.result;
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(content, file.name, number, null);
return false;
}
reader.readAsDataURL(file);
}else{
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(null, null, number, test);
return false;
}
}
function fileUploaded(status) {
document.getElementById("myForm").reset();
document.getElementById('output').innerHTML = status;
}
</script>
</head>
<body>
<div align="center">
<h1 align="center" style="color:darkblue">FAX APP</h1>
<h2 align="center">SEND OUTGOING FAX</h2>
<hr>
<form id="myForm" align="center">
<label for="pdf">Choose a PDF file to upload -- <b>OR</b>-- Check "SEND APPLICATION" </label>
<br>
<input id="pdf" type="file" name="myFile" >
<br><br>
<input type="checkbox" style="width:25px ; height:25px" name="entered">
<label for="entered" style="font-size:30px" > SEND APPLICATION</label>
<br><br>
<label for="phonenumber">Enter Destination Number</label>
<br>
<input id="phonenumber" type="text" name="Pnumber" placeholder="Phone Number" >
<br>
<input type="submit" value="SEND FAX" onclick="upload()" >
</form>
<p><b>FAX DELIVERY STATUS:</b></p>
<div id="output"align="center"><b></b></div>
<br>
<a href="https://drive.google.com/drive/folders/xxxxxxxxxxxxxxxx?usp=sharing"
target="_blank">SENT FAX DOCUMENTS</a>
</div>
</body>
</html>
I believe your goal as follows.
You want to remove the error when SEND APPLICATION is checked without selecting a file.
Modification points:
When the file is not selected, an error occurs at FileReader because file is undefined. I think that this might be the reason of your issue.
In this case, I would like to propose the function upload() at Javascript side as follows.
if (file && !test) {}else{} is used. By this,
When the file is selected AND SEND APPLICATION is not checked, the selected file is used.
When the file is not selected OR SEND APPLICATION is checked, the file of var appl = DriveApp.getFileById('xxxxxxxxx') is used.
About this, please modify the if statement for your actual situation.
Modified script:
When your script is modified, please modify upload() at Javascript side as follows.
function upload() {
var file = document.getElementsByName('myFile')[0].files[0];
var number = document.getElementsByName('Pnumber')[0].value;
var test = document.getElementsByName("entered")[0].checked;
// I modified below script.
if (file && !test) {
var reader = new FileReader();
reader.onload = function(e) {
var content = reader.result;
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(content, file.name, number, test);
return false;
}
reader.readAsDataURL(file);
} else {
google.script.run.withSuccessHandler(fileUploaded).uploadFiles(null, null, number, test);
}
}
In this modification, Google Apps Script side is not modified.
Added:
I think that your current issue is due to that you changed Google Apps Script from the script in the initial question. In the current script, name is removed at Google Apps Script and Javascript. By this, an error occurs at createFile. Please use name as follows.
From:
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'application/pdf');
To:
var blob = Utilities.newBlob(Utilities.base64Decode(blob[1]), 'application/pdf', "sample");
In this case, the filename is a temploral. So you can use various name like "sample", "temp" and so on.
And when you modified the script of Web Apps, please redeploy the Web Apps as new version. By this, the latest script is reflected to the Web Apps. Please be careful this.
And in your current script, if (!test) { is used. In this case, when the button is cliced without selecting file and cheking the checkbox, an error occrurs. Please be careful this.

the eSignature dilemma

I have a form that needs an eSignature collected via mobile. I need it to be free with unlimited responses. I have a working jSignature HTML code for Google Sheets, but I cannot get it to work on mobile.
Ideally, I'd like to stick with Google, though I've been experimenting outside of it with things like Wix (doesn't do exactly what I need it to) or Android Studio (beyond my ability). My ability beyond that isn't great by any means so I'm not sure where to begin, though I have a suspicion it isn't about what I can do so much as what google sheets can do, as in, I've read a bit about how scripting doesn't work well on mobile.
HTML
<!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 id="customerForm">
Please sign your name in the pad below: <br>
Full Name: <input type="text" name="username"><br>
Employee Number: <input type="employeenumber" name="useremployeenumber"><br><br>
Signature:
<div id="signature"></div><br>
<img id="rendered" src="" style="display:none">
<input type="button" value="Save" onclick="renderSignature();saveImage();"/>
</form>
</body>
<script>
document.getElementById("signature").style.border = "1px solid black";
$("#signature").jSignature({
'background-color': 'transparent',
'decor-color': 'transparent'
});
function renderSignature(){
$("img#rendered").attr("src",$('#signature').jSignature('getData','default'));
}
function saveImage(e){ //This sends the image src to saveImages function
var bytes = document.getElementById('rendered').src;
console.log(bytes);
var sign = {
username: document.getElementsByName('username')[0].value,
useremployeenumber: document.getElementsByName('useremployeenumber')[0].value
};
google.script.run.saveImage(bytes, sign);
return
}
window.onload=function(){
google.script.run
.withSuccessHandler(function(){google.script.host.close();})
.saveImage(bytes, sign);
}
</script>
</html>
CODE.GS
function showDialog() {
var html = HtmlService.createHtmlOutputFromFile('jSignature')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi()
.showModalDialog(html, 'Your Signature is Required');
}
function doGet() {
return HtmlService
.createTemplateFromFile('jSignature')
.evaluate();
}
function saveImage(bytes, sign){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('my page name');
var dateObj = Date.now();
var bytes = bytes.split(",")
var blob = Utilities.newBlob(Utilities.base64Decode(bytes[1]), 'image/png');
var fileName = blob.setName("Signature "+dateObj).getName();
var sigFolder = DriveApp.getFolderById("my folder id");
var url = sigFolder.createFile(blob).getId();
Logger.log(url)
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Register');
var name = sign.username;
var employeenumber = sign.useremployeenumber;
var signature = ss.insertImage(blob,4,ss.getLastRow()+1);
signature.setWidth(500);
signature.setHeight(20);
signature
var imageCell = ss.getRange(ss.getLastRow()+1, 1, 1, 3).setValues([[Date(), name,employeenumber]]);
}
What I've been thinking about is having the user open the form responses google sheet first, to a page with a link to the form. They would follow that link, fill out the form then be taken back to the google sheets form where an onFormSubmit trigger would bring up the jSignature pad. They would sign and all the information would be collected on one line in the form responses.
How do I make jSignature work for Google Sheets mobile? Is it even possible?

Google Sheets web app register several options

I've taken an example from a book to adapt it. the thing is that the original code has radio check (to enable only one option) and I'd like to have them as checkbocxes (to register several choices). I've made the changes in the HTML code and it looks fine but the spreadsheet still registers one of the choices instead of all of them.
Could you please let me know what I'm missing?
Here's the HTML of the project
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form method="post" action="<?= pubUrl ?>">
<h4>Where will you go for vacation?</h4>
<? for (var i in places) { ?>
<input type="checkbox" name="places"
value="<?= places[i] ?>" /><?= places[i] ?><br />
<? } ?>
<br />
<input type="submit" value="SUBMIT" />
</form>
</body>
</html>
And here's the GAS (google Script)
function doGet() {
// Replace with your spreadsheet's ID.
var ss = SpreadsheetApp.openById("1hpYbBbpVfxsciVCpZGBcqHPeBo2Wuj7U1Y9CaxsI9go");
var SheetPlaces = ss.getSheetByName("Places");
var data = SheetPlaces.getDataRange().getValues();
// Remove header row.
data.shift();
var places = [];
// Populate the places array with the first column's data.
data.forEach(function(row){
places.push(row[0]);
});
var template = HtmlService.createTemplateFromFile("form.html");
//Assign the published URL to the template object in the doGet
template.pubUrl = "https://script.google.com/macros/s/AKfycbx90heH12wfP4-kVZCOkEpI7Bi5wqpDAf-ndLrf3bPPYSwwEp5Q/exec";
//o
//template.pubUrl = ScriptApp.getService().getUrl();
// Assign the places array to the template object.
template.places = places;
var html = template.evaluate();
return HtmlService.createHtmlOutput(html);
}
function doPost(e){
// Replace with your spreadsheet's ID.
var ss = SpreadsheetApp.openById("1hpYbBbpVfxsciVCpZGBcqHPeBo2Wuj7U1Y9CaxsI9go");
var SheetResponses = ss.getSheetByName("Responses");
// Create a 'Responses' sheet if it does not exist.
if(!SheetResponses){ SheetResponses = ss.insertSheet("Responses");
}; SheetResponses.appendRow([e.parameter.places]); return ContentService.createTextOutput( "Your response submitted successfully. Thank you!" );
}
function createForm() {
var ThisSpreadsheet = SpreadsheetApp.getActive();
var SheetPlaces = ThisSpreadsheet.getSheetByName("Places");
// Load 'Places' sheet data as a 2-dimensional array.
var data = SheetPlaces.getDataRange().getValues();
// remove the header row
data.shift();
var places = [];
// Populate the places array with the first column's data
data.forEach(function(row){
places.push(row[0]);
});
// Create a new form
var form = FormApp.create("Vacation Form");
form.addMultipleChoiceItem()
.setTitle('Where will you go for a vacation?')
.setChoiceValues(places)
.showOtherOption(true)
}
Also, here's the web app url
https://script.google.com/macros/s/AKfycbx90heH12wfP4-kVZCOkEpI7Bi5wqpDAf-ndLrf3bPPYSwwEp5Q/exec
Thanks for your help!