Put together this script that will upload a file to my google drive.
I need it to be able to handle either a big .zip file, OR multiple image files.
Currently it times out if you upload a big .zip file (around 7MB)
I would prefer to have it upload multiple files.
Apps Script:
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('form.html');
}
function uploadFiles(form) {
try {
var unitNumber = form.unitNumber;
if (unitNumber == "") {
unitNumber = "";
} else {
unitNumber = " #" + unitNumber;
}
var foldertitle = form.streetAddress + unitNumber + ' ' + form.cityName + ' ' + form.stateName + ' - ' + form.businessName + ' ' + form.managerName + ' - ' + form.propertyType;
var folder, folders = DriveApp.getFolderById("0B0V8-0eo7tx8MTQzcGFwdXF6SFU");
var createfolder = folders.createFolder(foldertitle);
folder = createfolder;
var blob = form.filename;
var file = folder.createFile(blob);
return "File uploaded successfully ";
} catch (error) {
Logger.log('err: ' + error.toString());
return error.toString();
}
}
Form Code
<body>
<div id="formcontainer">
<form id="myForm">
<div>
<input type="text" name="businessName" placeholder="Business Name">
</div>
<div>
<input type="text" name="managerName" placeholder="Manager Name">
</div>
<div>
<input type="text" name="streetAddress" placeholder="Street Address">
</div>
<div>
<input type="text" name="unitNumber" placeholder="Unit Number">
</div>
<div>
<input type="text" name="cityName" placeholder="City">
</div>
<div>
<input type="text" name="stateName" placeholder="State">
</div>
<br>
<label for="propertyType">Choose Type</label>
<br>
<select name="propertyType">
<option value="Interactive Floor Plan">IFP</option>
<option value="Pictures Only">Pictures</option>
<option value="Video Only">Video</option>
<option value="Complete Property">All</option>
</select>
<br>
<label for="myFile">Compress All Files into .zip file</label>
<br>
<input type="file" name="filename" id="myFile" multiple>
<input type="submit" value="Upload File" onclick="this.value='Uploading..';
google.script.run.withSuccessHandler(fileUploaded)
.uploadFiles(this.parentNode);
return false;">
</form>
</div>
<div id="output"></div>
<script>
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
body {
max-width: 400px;
padding: 20px;
margin: auto;
}
input {
display: inline-block;
width: 100%;
padding: 5px 0px 5px 5px;
margin-bottom: 10px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
select {
margin: 5px 0px 15px 0px;
}
input[type="submit"] {
width: auto !important;
display: block !important;
}
input[type="file"] {
padding: 5px 0px 15px 0px !important;
}
</style>
</body>
I don't see other way to make GAS work with multiple files if not with multiple files inputs. You can add dinamically input with Jquery (or plain Javascript), and test in the server side to check how many input files got carried over.
Like so:
in HTML:
<input type="file" name="filename0" id="myFile"><div id="moreInputs"></div>
<button onClick="moreFieds()">Add more Fieds</button>
<script>
var numInputs = 1;
function moreFieds(){
$('#moreInputs').append($('<input type="file" name="filename'+numInputs+'" id="myFile">'));
numInputs++;
}
</script>
In code.gs:
var numForms = 0;
while( form[ (filename + numForms) ] ){
var blob = form[ (filename + numForms) ];
var file = folder.createFile(blob);
numForms++;
}
Or as I like more, send files inputs one by one in the script, giving each input it's own form, that way you can know when each file has done loading with the successHandler.
Related
I need to display a specific html output following a condition on a variable ("tvs" a boolean).
I created the 2 html files in another spreadsheet and tested them OK.
Then I copy&pasted the samples in my much bigger spreadsheet and it doesn't work. Well, it works when i debug each 'show' functions but not in the execution of the spreadsheet.
My script goal is to detect change in a column (process info near the change occurred), then launch modal dialogs from html files (2 possible files).
GS code:
function onEdit(e) {
var celluleRef = e.range.getA1Notation()
GLOBALVAR.setProperty('CELLREF', celluleRef);
var cas = DetectCas(celluleRef) // do stuff, return cas = 0 or 1 or 2.
if (cas == 0) {
return
}
var tvs = SiTvs(celluleRef) // do stuff, return tvs as boolean.
tvs ? showPageTvs() : showPageVide();
}
function showPageTvs() {
//SpreadsheetApp.getUi().alert("cas : page tvs") //THIS SHOWS when called
var ui = SpreadsheetApp.getUi();
var htmlTvs = HtmlService.createTemplateFromFile('PageTvs')
.evaluate()
.setHeight(600);
ui.showModalDialog(htmlTvs, 'Confirmation');
}
function showPageVide() {
// SpreadsheetApp.getUi().alert("cas : page vide") //THIS SHOWS when called
var htmlVide = HtmlService.createHtmlOutputFromFile('PageVide')
.setWidth(400);
SpreadsheetApp.getUi()
.showModalDialog(htmlVide, 'Confirmation');
}
Then the html files :
PageVide.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body{
font-size:25px;
}
input.largerCheckbox {
width: 20px;
height: 20px;
}
</style>
</head>
<body>
Gamme vide, quelle est votre action ?<br><br>
<form id="myForm" onsubmit="google.script.run.processForm(this)">
<div>
<input class="largerCheckbox" type="checkbox" id="ConfP" name="ConfP">
<label for="ConfP">Confirmation totale Prod</label>
</div>
<div>
<input class="largerCheckbox" type="checkbox" id="ConfQ" name="ConfQ">
<label for="ConfQ">Confirmation totale Qls</label>
</div>
<div>
<br>
<input class="largerCheckbox" type="checkbox" id="Tvs" name="Tvs">
<label for="Tvs">TVS :</label>
</div>
<input style="font-size:25px" type="text" name="TvsText"><br><br>
<input style="font-size:25px; float: left" type="submit" value="Submit">
</form>
<input style="font-size:25px; float: right" type="button" value="Annuler" onclick="google.script.host.close()" />
</body>
</html>
PageTvs.html :
I add that function "decoupe" just add some checkboxes.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body{
font-size:25px;
}
input.largerCheckbox {
width: 20px;
height: 20px;
}
p {
text-indent: 10%;
}
fieldset {
input[type=checkbox] {
text-indent: 20%;
}
}
</style>
</head>
<body>
Gamme en TVS, quelle est votre action ?<br><br>
<form id="myForm" onsubmit="google.script.run.processForm(this)">
<div>
<input type="checkbox" class="largerCheckbox" id="ConfP" name="ConfP">
<label for="ConfP">Confirmation totale Prod</label>
</div>
<div>
<input type="checkbox" class="largerCheckbox" id="ConfQ" name="ConfQ">
<label for="ConfQ">Confirmation totale QLS</label>
</div>
<p>Confirmation partielle :
<fieldset>
<?!= decoupe() ?>
</p>
</fieldset>
<br>
<input style="font-size:25px; float: left" type="submit" value="Valider">
</form>
<input style="font-size:25px; float: right" type="button" value="Annuler" onclick="google.script.host.close()" />
</body>
</html>
I need to understand why html doesn't show (except in debug) and if anything hurt your eyes, tell me !
I think the problem is that you do not have permission to call Ui.showModalDialog() because onedit is a simple trigger.
The following works on an installable trigger but not on a simple trigger:
function showMyTestDialog1() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'Test1');
}
function showMyTestDialog2() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile('ah1'), 'Test2');
}
function onMyEdit(e) {
e.source.toast('entry');
const a1 = e.range.getA1Notation();
const sh = e.range.getSheet();
if (sh.getName() == 'Sheet2' && e.range.columnStart == 1 && e.range.rowStart > 1) {
e.source.toast('cond')
let v = e.range.rowStart % 3 == 0;
v ? showMyTestDialog1() : showMyTestDialog2();
}
}
If you had checked your execution log you would have seen an error like this:
Exception: You do not have permission to call Ui.showModalDialog. Required permissions: https://www.googleapis.com/auth/script.container.ui
at showMyTestDialog2(ag1:5:26)
at onEdit(ag1:16:31)
I found something wrong with your style in PageTvs.html
<style>
body{
font-size:25px;
}
input.largerCheckbox {
width: 20px;
height: 20px;
}
p {
text-indent: 10%;
}
fieldset {
input[type=checkbox] {
text-indent: 20%;
}
}
</style>
You should put fieldset input[type=checkbox] next to each other.
Like this:
fieldset input[type=checkbox] {
text-indent: 20%;
}
w3schools: css selectors
When I select the update function, I need the pop-up interface to gather the information on the Row that you are currently on in the sheet and fill in.
Then the user can change the information to update. but not the top 3 boxes. these would only view only.
please help.
I have tried changing the Html code but not getting the information from the row, the information I enter submits correctly.
I have researched this site and others but cannot find any information on getting this to populate the popup interface box.
function inputUpdates_() {
var html = doGet();
SpreadsheetApp.getUi().showModalDialog(html, 'Update Techicians Training Dates & Comments');
}
//Create a Data Entry Form
function doGet() {
var result = HtmlService
.createTemplateFromFile('Form')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
result.setHeight(600);
result.setWidth(500)
return result;
}
//The function retrieves the data from the return form and fills the spreadsheet
function getValuesFromForm(form){
var first_name = form.first_name,
last_name = form.last_name,
student_id = form.student_id,
training_date = form.training_date,
seam_sealer = form.seam_sealer,
filler_repair = form.filler_repair,
corrosion_protection = form.corrosion_protection,
body_filler_repair = form.body_filler_repair,
plasic_repair = form.plasic_repair,
bonding = form.bonding,
sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('List')
var lastRow = sheet.getLastRow();
sheet.getRange(lastRow + 1, 1).setValue(first_name);
sheet.getRange(lastRow + 1, 2).setValue(last_name);
sheet.getRange(lastRow + 1, 3).setValue(student_id);
sheet.getRange(lastRow + 1, 4).setValue(training_date);
sheet.getRange(lastRow + 1, 5).setValue(seam_sealer);
sheet.getRange(lastRow + 1, 6).setValue(filler_repair);
sheet.getRange(lastRow + 1, 7).setValue(corrosion_protection);
sheet.getRange(lastRow + 1, 8).setValue(body_filler_repair);
sheet.getRange(lastRow + 1, 9).setValue(plasic_repair);
sheet.getRange(lastRow + 1, 10).setValue(bonding);
}
<script type="text/javascript">
function formSubmit() {
google.script.run.getValuesFromForm(document.forms[0]);
google.script.host.close();
}
</script>
<style>
input.i01 {
margin-left: 84px;
}
input.i02 {
margin-left: 85px;
}
input.i03 {
margin-left: 81px;
}
input.i04 {
margin-left: 68px;
}
input.i05 {
margin-left: 73px;
}
input.i06 {
margin-left: 79px;
}
input.i07 {
margin-left: 12px;
}
input.i08 {
margin-left: 34px;
}
input.i09 {
margin-left: 75px;
}
input.i10 {
margin-left: 112px;
}
input.i11 {
margin-left: 170px;
}
<p><font face="verdana" color="green">
</style>
<!--Login Form -->
<div id="logindiv">
<form method="POST">
<label><p><font face="verdana" color="blue">First Name: </label>
<input class="i01" type="text" name="firstName"/>
<br/>
<br/>
<label>Last Name: </label>
<input class="i02" type="text" name="last_name" /><br/>
<br/>
<label>Student Id: </label>
<input class="i03" name="student_id" list="techid" type="text" />
<datalist id="techid">
<? var data = studentid(); ?>
<? for (var i = 0; i < data.length; i++) { ?>
<option value="<?= data[i]?>"></option>
<? } ?>
</datalist>
<br/>
<br/>
<label>Training Date: </label>
<input class="i04" type="date" name="training_date" /><br/>
<br/>
<label>Seam Sealer: </label>
<input class="i05" type="date" name="seam_sealer" /><br/>
<br/>
<label>Filler Repair: </label>
<input class="i06" type="date" name="filler_repair"/><br/>
<br/>
<label>Corrosion Protection: </label>
<input class="i07" type="date" name="corrosion_protection" /><br/>
<br/>
<label>Body Filler Repair: </label>
<input class="i08" type="date" name="body_filler_repair"/><br/>
<br/>
<label>Plasic Repair: </label>
<input class="i09" type="date" name="plasic_repair"/><br/>
<br/>
<label>Bonding: </label>
<input class="i10" type="date" name="bonding" /><br/>
<br/>
<br/>
<br/>
<input class="i11" onclick="formSubmit()" type="button" value="Submit" />
<input onclick="google.script.host.close()" type="button" value="Exit" />
<br/></font></p>
</form>
I have resorted to using Bootstrap popover because HTML validation exhibits the same behavior I am now experiencing. Perhaps the solution for one will work for both.
JS
var validate = validate || {};
validate.issueError = function ($elem, msg, placement) {
placement = placement == undefined ? 'bottom' : placement;
$elem.attr('data-toggle', 'popover');
$elem.attr("data-offset", "0 25%");
var exclamationPoint = "<span style='font-weight: bold; font-size:medium; color: white; background-color: orange; height: 12px; padding: 1px 6px; margin-right: 8px;'>!</span>";
var content = "<span style='font-size: smaller;'>" + msg + "</span>";
$elem.popover("destroy").popover({
html: true,
placement: placement,
content: exclamationPoint + content
})
$elem.focus();
$elem.popover('show');
setTimeout(function () { $elem.popover('hide') }, 5000);
$elem.on("keydown click", function () {
$(this).popover('hide');
$(this).off("keydown click")
})
}
validate.edits = {
required: function ($form) {
var $reqFlds = $form.contents().find('[required], [data-required]');
$reqFlds.each(function () {
var $this = $(this);
var result = ($this.filter("input, select, textarea").length) ? $this.val() : $this.text();
if (!$.trim(result)) {
validate.issueError($this, "Please fill out this field.");
return false;
}
});
return true;
}
HTML (note I have substituted "required' with "data-required" to force the Bootstrap routines).
<!DOCTYPE html>
<html>
<head>
<title>Writer's Tryst - Writers Form</title>
<link type="text/css" href="css/writers.css" rel="stylesheet" />
<style>
body {padding: 0 20px;}
.limited-offer {
background-color: white;
padding: 3px;
margin-bottom: 12px;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="container-fluid">
<img id="img-writers" src="#" alt="images" />
<form id="form-writers" method="post" class="form-horizontal well">
<h1>Writers</h1>
<div class="form-group">
<label for="title" class="col-lg-3 control-label">Title</label>
<div class="col-lg-9">
<input type="text" class="form-control" data-required id="title" name="title" autofocus="true" placeholder="Title" />
</div>
</div>
<div class="form-group">
<label for="form-type" class="col-lg-3 control-label">Type of work</label>
<div class="col-lg-9">
<select class="form-control" data-required id="form-type" name="form-type"></select>
</div>
</div>
<div class="form-group">
<label for="genre" class="control-label col-lg-3">Genre</label>
<div class="col-lg-9">
<select id="genre" name="genre" class="form-control" data-required></select>
</div>
</div>
<div class="form-group">
<label for="nbr-pages" class="control-label col-lg-3">Number Pages</label>
<div class="col-lg-9">
<input type="number" id="nbr-pages" name="nbr-pages" class="form-control" data-required placeholder="Pages" />
</div>
</div>
<div id="tips">The objective of a synopsis or query letter is to entice enablers into requesting your manuscript.
It must be concise and to the point and of course very well written. One page is preferred and no more than 3 pages will be accepted.
Sample Query Letter
</div>
<p id="file-warning" class="thumbnail">Your synopsis/query letter must be a PDF file.
<a target="_blank" href="https://www.freepdfconvert.com/" target="_blank">Free file conversion to PDF.</a>
</p>
<div>
<a id="file-upload" class="btn btn-custom-primary btn-file btn-block text-xs-center" role="button">Choose PDF to Upload
<br/><div id="filename" class="btn-block" style="color: #fff">No file chosen</div>
</a>
<input type="file" id="file2upload" style="display: none">
</div><br/>
<div class="form-group">
<!-- <button type="submit" id="writers-submit" class="btn btn-custom-success btn-block m-t-8">Submit</button>-->
</div>
<div class="limited-offer">For a limited time, writer submissions will cost <span style="color: #f00; font-weight:bold">$15.00</span> to offset screening and editing costs and to promote quality synopsises and query letters. We reserve the right to change this policy without notice.</div>
<!-- <form id="form-paypal" name="form-paypal" action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top" onsubmit="return ajaxSubmit()">-->
<form id="form-paypal" name="form-paypal" method="post" target="_top">
<input type="submit" class="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="U2LE82Z45PJ54">
<input style="display: block; margin: 0 auto;" id="but-pp" type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_paynowCC_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="PayPal" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
<input id="userid" name="userid" type="hidden" />
<input id="filesize-limit" name="filesize-limit" type="hidden" value="150000" />
</form>
</div>
<script>
angular.element(document).ready(function () {
showImages($("#form-writers"), $("#img-writers"), "authors", ["blake.jpg", "Melville.jpg", "lewis-carroll.jpg", "stephen-king.jpg", "twain.jpg", "camus.jpg", "nietzsche.jpg", "hesse.jpg"]);
});
$(function () {
populateWritersDropdowns();
$(document).on('change', ':file', function () {
var input = $(this),
numFiles = input.get(0).files ? input.get(0).files.length : 1,
label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
input.trigger('fileselect', [numFiles, label]);
});
$('#file-upload').on('click', function (e) {
e.preventDefault();
$('#file2upload')[0].click();
});
$("#file2upload").on("change", function () {
var filepath = $('#file2upload')[0].value;
var filename = filepath.substr(filepath.lastIndexOf("\\") + 1);
$("#filename").text(filename)
});
$("#but-pp").on("mousedown", function (e) {
//if (!$("#form-writers").get(0).checkValidity()) return false;
var $ret = validate.edits.required($("#form-writers"));
alert($ret.length);
if ($ret != true) {
$ret.focus();
return false;
}
if (!validate.edits.requireFile($("#filename"))) return false;
if (!fileEdits()) return false;
ajaxSubmit();
function fileEdits() {
var fileSizeLimit = $("#filesize-limit").val();
var file = document.getElementById('file2upload').files[0];
var fileName = file.name;
var fileExt = fileName.substring(fileName.lastIndexOf(".") + 1);
var fileSize = file.size;
if (fileSize > fileSizeLimit) {
showMessage(0, "Your file-size (" + (Math.round(parseInt(fileSize) / 1000)).toLocaleString() + "kb) exceeds the limit of " + (fileSizeLimit.toLocaleString() / 1000) + "kb");
return false;
} else {
if (fileExt.toLowerCase() != "pdf") {
showMessage(0, "Your synopsis / query letter MUST be a PDF file.");
return false;
};
return true;
}
};
function ajaxSubmit() {
var file_data = $('#file2upload').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
form_data.append('action', "upload");
form_data.append('title', $("#title").val());
form_data.append('form-type', $("#form-type").val());
form_data.append('genre', $("#genre").val());
form_data.append('nbr-pages', $("#nbr-pages").val());
form_data.append('account-id', localStorage.getItem("account-id"));
ajax('post', 'php/writers.php', form_data, success, 'Error uploading file:', 'text', false, false, false);
function success(result) {
if (result.indexOf("PDF") == -1) {
showMessage(1, "Your submission will go live and you will be notified after our reviews are complete.");
var data = {};
data['writer-id'] = result;
ajax('post', 'php/paypal-ipn.php', data, listenerStarted);
function listenerStarted(result) {
alert("pp=" + result);
}
} else {
showMessage(0, result);
}
setTimeout(function () {
document.getElementById('form-writers').reset();
$("#filename").text("No file chosen");
}, 5000);
};
};
});
});
</script>
</body>
</html>
I am making a thing for setting goals,and to show your progress, I use the progress element. I would like to save my goal with php/js/other to a .txt file on my server called user.txt. I have already tried this Write server text files with Ajax and PHP write file from input to txt shows what I want, but instead of form tags, I want just 2 input fields
Is there any way I can merge these 2 files to save my data from my 2 fields to a text file(user.txt)
Here is my code:
function myFunction() {
var x = document.getElementById("myTextarea").value;
document.getElementById("myProgress").value = x;
}
function myFunction2() {
var x = document.getElementById("myTextarea2").value;
document.getElementById("myProgress").max = x;
}
progress {
color: #0063a6;
font-size: .6em;
line-height: 1.5em;
text-indent: .5em;
width: 30em;
height: 3em;
border: 1px solid #0063a6;
background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>Goal Progress:</h3>
<progress id="myProgress" value="0" max="100">
</progress>
<hr>
<input type="text" id="myTextarea"></input>
<button onclick="myFunction()">Add</button>
<hr>
<input type="text" id="myTextarea2" />
<button onclick="myFunction2()">Set Goal</button>
<hr>
here I finally solved my perplexing paradyme:
<html>
<body onload="timer=setTimeout('myFunction2(); myFunction();',3000)">
<style>
progress {
color: #0063a6;
font-size: .6em;
line-height: 1.5em;
text-indent: .5em;
width: 30em;
height: 3em;
border: 1px solid #0063a6;
background: #fff;
}
</style>
<h3>Goal Progress:</h3>
<progress id="myProgress" value="0" max="100">
</progress>
<hr>
<form action="form.php" method="POST">
add money:
<input type ="text" name="field1" id="myTextarea"></input>
<hr>
Goal:
<input type ="text" name="field2" id="myTextarea2"/>
<input type="submit" name="submit" value="Save Data">
</form>
<hr>
<button onclick="myFunction2(); myFunction();">show new progress</button>
<script>
function myFunction() {
var x = document.getElementById("myTextarea").value;
document.getElementById("myProgress").value = x;
}
function myFunction2() {
var x = document.getElementById("myTextarea2").value;
document.getElementById("myProgress").max = x;
}
</script>
</body>
</html>
I have this form I created in HTML (called form.html) written in google apps script and I also have a stylesheet (CSS) to go with that. All is working well when I have the CSS in the same HTML-file as the form. However if I want to put my stylesheet in a separate HTML-file (called Stylesheet.html) and then include it in the form.html by using a scriplet
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
or even creating an 'include' function:
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.getContent();
}
and then in form.html
<?!= include(Stylesheet) ?>
..it doesn't seem to work. What's even worse the scriplet shows up on the form.
Maybe there is something basic I am overlooking, but I can't wrap my head around this. Any ideas ?
Here is the code so far...
function doGet() {
return HtmlService.createHtmlOutputFromFile('Formulier')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.getContent();
}
function materiaalLijst(afdnum) {
return SpreadsheetApp.openById('1l6MKG61GHMFSZrOg04W4KChpb7oZBU9VKp42FPXmldc')
.getSheetByName('RESERVATIE')
.getDataRange()
.getValues()
.map(function (v) {
return v[Number(afdnum) - 1]
})
.splice(1);
}
//work in progress
function processForm(form) {
Logger (form); //array containing form elements
}
<style>
form {
/* Just to center the form on the page */
margin: 0 auto;
width: 400px;
/* To see the outline of the form */
padding: 1em;
border: 1px solid #CCC;
border-radius: 1em;
}
form div + div {
margin-top: 1em;
}
label {
/* To make sure that all labels have the same size and are properly aligned */
display: inline-block;
width: 90px;
text-align: right;
}
input, textarea {
/* To make sure that all text fields have the same font settings
By default, textareas have a monospace font */
font: 1em sans-serif;
/* To give the same size to all text field */
width: 300px;
-moz-box-sizing: border-box;
box-sizing: border-box;
/* To harmonize the look & feel of text field border */
border: 1px solid #999;
}
input:focus, textarea:focus {
/* To give a little highlight on active elements */
border-color: #000;
}
textarea {
/* To properly align multiline text fields with their labels */
vertical-align: top;
/* To give enough room to type some text */
height: 5em;
/* To allow users to resize any textarea vertically
It does not work on every browsers */
resize: vertical;
}
</style>
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
<form id="myForm">
<!-- Text input field -->
<div>
<label for="name">Naam:</label>
<input type="text" id="name" placeholder="Voornaam + naam" required>
</div>
<div>
<label for="mail">E-mail:</label>
<input type="email" id="mail" required>
</div>
<div>
<label for="Afdeling">Afdeling:</label>
<input type="radio" id="1" name="Afd" value="Oostende">Oostende
<input type="radio" id="2" name="Afd" value="Brugge">Brugge
<input type="radio" id="3" name="Afd" value="Westhoek">Westhoek
</div>
<div>
<label for="datepicker">Datum:</label>
<input type="date" id="resdatum" required>
</div>
<div>
<label for="timepicker">Uur:</label>
<input type="time" id="restijd" required>
</div>
<div>
<label for="Frequentie">Frequentie:</label>
<input type="radio" name="freq" value="éénmalig" required>éénmalig
<input type="radio" name="freq" value="meermaals">voor meerdere weken
</div>
<div>
<label for="Materiaal">Materiaal:</label>
<select id="materiaal" name="materiaalselectie" required>
<option value="notSel">Kies..</option>
</select>
</div>
<div>
<!-- The submit button. It calls the server side function uploadfiles() on click -->
<input type="submit" id="verzenden" name="verzenden" class="verzenden" value="Reservatie verzenden" >
</div>
<div id="output"></div>
</form>
<div id="output"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
$("input:radio[name=Afd]").click(function() {
go(this.id);
});
function go(idAfd) {
google.script.run.withSuccessHandler(showList).materiaalLijst(idAfd);
}
function showList(things) {
var list = $('#materiaal');
list.empty();
for (var i = 0; i < things.length; i++) {
list.append('<option value="' + things[i] + '">' + things[i] + '</option>');
}
}
//below is work in progress...
$('#myForm').submit(function(e) {
e.preventDefault();
var arr =[];
//var fields = $( ":input" ).serializeArray();
$.each( $( ":input" ).serializeArray(), function( i, field ) {
arr.push( field.value);
});
var json = JSON.stringify($('#myForm').serializeArray());
google.script.run.processForm(arr);
alert(arr);
})
</script>
The result with CSS IN the form.html
and here is the CSS in a separate .html file and included
in form.html with
<?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
You're doing this right:
Your css file must be an HTML file, as those are the only type supported by HtmlService. If you look at the starter scripts, you'll find that they have Stylesheet.html, with content:
<!-- This CSS package applies Google styling; it should always be included. -->
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<style>
...
</style>
You know the google css is working if your sidebar or dialog looks pretty much like google stuff - same font, same text size. To have an action button be blue, you need to add the appropriate class to it, class="action".
Why isn't yours working?
Get ready for a face-palm moment...
You're using scriptlets, part of the Html Service templated HTML. They require interpretation, which is not done by HtmlService.createHtmlOutputFromFile(). (That's why you see the scriptlet line literally.)
Instead, you need to read the file containing scriptlets as a template, and then .evaluate() it.
function doGet() {
return HtmlService.createTemplateFromFile('form')
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
To display the google-themed action button, include the Apps Script CSS and add "action" class:
<input type="submit" id="verzenden" name="verzenden" class="action verzenden" value="Reservatie verzenden" >
How about to name it Stylesheet.css?
And try to include it via normal HTML in the header.
<link rel="stylesheet" href="Stylesheet.css" type="text/css">
HTH