So, I got to build a script that asks the user for some information using google apps script. Those codes must be in a specific spreadsheet (1st URL), so does the HTML form that will be loaded by a modal dialog.
Even though the code is written in the spreadsheet SCRIPTS, that project is loaded as a library on the project from spreadsheet workbook, and that's the spreadsheet that will create a menu that will load the code from SCRIPTS.
The final goal is: the user opens workbook, runs the item from MyMenu > Form
, a modal/form is opened; the user writes his info and hits submit. After that, the function saveData
from SCRIPTS, which will write the informations in the spreadsheet requests.
Obs.: since saveData
needs to call 2 methods hosted in the SCRIPTS project, it also needs to be hosted in the same project.
Some code that might be helpful for you:
Project: workbook
// Code.gs
function onOpen() {
SpreadsheetApp.getUi().createMenu('MyMenu').addItem('Form', 'closeKits').addToUi();
}
// CloseKits.gs
function closeKits() {
scripts.showForm();
}
function callLibraryFunction(data){
scripts.saveData(data);
}
appsscript.json
{
"timeZone": "America/New_York",
"dependencies": {
"libraries": [
{
"userSymbol": "scripts",
"version": "0",
"libraryId": "1AhbUglj05OrQuaZFqQcL_0UB7MCGope2YpVnE7eOGYjdxiXug0DiDA1i",
"developmentMode": true
}
]
},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8"
}
Project SCRIPTS:
<!-- Form.html -->
<!DOCTYPE html>
<html>
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material Icons" rel="stylesheet">
<!--Import materialize.css-->
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<div >
<form >
<div >
<label for="requestedBy">Requested By</label>
<input id="requestedBy" type="text" placeholder="John Doe" >
</div>
<div >
<label for="dueDate">Due Date</label>
<input id="dueDate" >
</div>
<div >
<label for="comments">Comments</label>
<textarea id="comments" placeholder="Please ignore lines X, Y and Z..." ></textarea>
</div>
<div >
<button id="btn">
Submit
</button>
</div>
</form>
</div>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
var options = {
autoClose: true,
format: 'mm/dd/yyyy',
defaultDate: new Date(),
setDefaultDate: true,
showClearBtn: true
};
document.addEventListener('DOMContentLoaded', function() {
var elements = document.querySelectorAll('.datepicker');
var instances = M.Datepicker.init(elements, options);
});
document.getElementById('btn').addEventListener('click', getData);
function getData() {
var requestedBy = document.getElementById('requestedBy').value;
var dueDate = document.getElementById('dueDate').value;
var comments = document.getElementById('comments').value;
var data = {
requestedBy: requestedBy,
dueDate: dueDate,
comments: comments
};
google.script.run.callLibraryFunction(data);
}
</script>
</body>
</html>
Here I had to use that callLibraryFunction
present in the Code.gs
from workbook in order to call the library function saveData
, since that last method is not visible to the HTML client running on workbook.
// SaveData.gs
function saveData(data) {
const iasRequestsSpreadsheet = SpreadsheetApp.openById('1o8JbVelmSNoGn6sn7laatBam_2WTtToB_nlZMTFY_Rg');
const sheet = iasRequestsSpreadsheet.getSheetByName('page1');
const line = getFirstEmptyRow(sheet);
// requested by
sheet.getRange(line, 2).setValue(data.requestedBy);
// due date
sheet.getRange(line, 6).setValue(data.dueDate);
// comments
sheet.getRange(line, 9).setValue(data.comments);
}
// ShowForm.gs
function showForm() {
const form = HtmlService.createTemplateFromFile('Form').evaluate().setHeight(480);
SpreadsheetApp.getUi().showModalDialog(form, 'Form');
}
// GetFirstEmptyRow.gs
function getFirstEmptyRow(sheet) {
const column = sheet.getDataRange();
const values = column.getValues();
let row = 0;
for (row; row<values.length; row ) {
if (!values[row].join("")) {
break;
}
}
return (row 1);
}
Please feel free to ask any other information in order to solve this, and also access those spreadsheets and run once the onOpen
from workbook, so it requests the required permissions to you.
EDIT:
As asked, after clicking submit
, on the spreadsheet workbook
I get only this in the logs:
CodePudding user response:
Well, apparently it was something with the browser... On my job notebook it worked using the edge, and for my colleagues it worked both on chrome and edge. But I still don't know what is the incompatibility here.