Getting value of arbitrary form element in Google Apps Script web app - forms

I have a Google Apps Script web app which has a form attached, for example:
<form id="form">
<input type="range" min="0" max="3" name="mb1" value="0">
<input type="range" min="0" max="3" name="mb2" value="0">
<input type="range" min="0" max="3" name="mb3" value="0">
etc...
<input id="submit" type="submit" style="display: none" onclick="this.value='Submitting ...'; google.script.run.withSuccessHandler(formSubmitted) .writeForm(this.parentNode); return false;">
</form>
The Code.gs file has a writeForm(form) function, which can access the form input values like so:
var mb1 = form.mb1;
var mb2 = form.mb2;
etc...
However, this approach is inefficient with many such inputs (I have around 80). Much better would just be to get the values when they're being processed in a loop, like so:
for(var i = 0; i <= 80; i++) {
var formItemID = "mb"+i;
console.log(form.formItemID);
}
However, this of course does not work, as it looks for form inputs with the id "formItemID". I've taken a look at some functionality of the HTMLFormElements class which should be being sent, but Apps Script doesn't seem to implement this fully, and I can't find documentation of the form.ItemName property. Is there a way to achieve this functionality without calling for each form input separately?

You could always just loop through the form elements and get the input values. This will send an array to the server.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="form" name="form">
<input class="range" type="range" min="0" max="3" value="0">
<input class="range" type="range" min="0" max="3" value="0">
<input class="range" type="range" min="0" max="3" value="0">
<br>
<input id="button" type="button" onclick="onClick()">
</form>
<script>
function onClick() {
var form = document.getElementById("form");
var vals = [];
for( var i=0; i<form.elements.length; i++ ) {
if( form.elements[i].className === "range" ) {
vals.push(form.elements[i].value);
}
}
google.script.run.getForm(vals);
}
</script>
</body>
</html>

Server side, Your form is sent as a object with key as input name and value as input values. Your form will look like:
{
mb1:0,
mb2:1,
mb3:0
}
To access the values, You can use form.mb1 as you've used or form['mb1']. To use variables as keys, always use the bracket [] notation
for(var i = 0; i <= 80; i++) {
var formItemID = "mb"+i;
console.log(form[formItemID]);//Note bracket notation
}
Or without a for loop,
var valuesArr = Object.keys(form).map(function(key){return form[key];})

Related

using onclick from HTMLservice to run multiple tasks

In the following code, I wanted the button "Add Lines" to:
run the function 'MoreRentals_fromSidebar' from code.gs in the SpreadsheetApp
then "google.script.host.close();" to close the sidebar
When I try to stack the commands, nothing happens. If I try to invoke the submitForm function to run the two commands, nothing happens (although I thought this was working last week and has now stopped).
Any suggestions would be appreciated.
<!DOCTYPE html>
<script>
function getDataFromHtml(idData) {
if (!idData)
idData = "mydata_htmlservice";
var dataEncoded = document.getElementById(idData).innerHTML;
var data = JSON.parse(atob(dataEncoded));
return data;
}
function initialize() {
var data = getDataFromHtml();
// I would have expected to be able to accept the two parameters but whichever is coded second does not get set.
//document.getElementById("myAgency").innerText = data.agency;
//document.getElementById("myRow").innerText = data.row;
// My workaround is to create the header of the sidebar to contain the agency and the line number
var arr = data.first.split("##");
document.getElementById('myTitle').innerText = arr[0]+"\n# line "+arr[1];
//alert(arr[0]+"\n\n"+arr[1]); // used for debugging
}
window.onload = initialize; //Note that there is no "()". It must be this way for this to work!
</script>
<html>
<head>
<base target="_top">
<script>
function submitForm() {
//alert('in submitForm: '+document.getElementById("RentalLinesForm");
google.script.run.MoreRentals_fromSidebar(document.getElementById('RentalLinesForm'));
google.script.host.close();
}
</script>
</head>
<body>
<h1 id="myTitle" ></h1>
<form id="RentalLinesForm">
<label for="numLines">Number of lines to add</label>
<input type="text" id="numLines" name="numLines"><br><br>
<div>
<label for="location">Where to place the new lines:</label><br>
<input type="radio" id="above" name="location" value="above">
<label for="above">Above line</label><br>
<input type="radio" id="below" name="location" value="below">
<label for="below">Below line</label><br>
<input type="radio" id="bottom" name="location" value="bottom">
<label for="bottom">At bottom</label>
<br><br><input type="button" value="Add Lines" onclick="google.script.run.MoreRentals_fromSidebar(document.getElementById('RentalLinesForm'));">
<br><br><input type="button" value="DONE" onclick="google.script.host.close();">
</form>
</body>
</html>

Required for the first or second input form

I use Bootstrap 4.5, where it is possible to check the filling of the form, for example by inserting required.
<input type="text" class="form-control" name="name_1" required>
How can I please check where I need to have input #1 OR input #2 filled in?
<input type="text" class="form-control" name="name_1">
<input type="text" class="form-control" name="name_2">
if you want to check whether the input#1 OR input#2 is filled. I recommend you to write a piece of javascript code to check that. if you are familiar with java script, create a separate javascript file and write a function to validate. or else you can just put a script tag inside the head tag as follows.
Javascript Validation:
<head>
<script>
function validateForm(){
if(document.myform.input1.value == "" || document.myform.input2.value == ""){
alert("Both input1 and input2 should not be empty!");
}
}
</script>
</head>
HTML form:
<form name="myform" method="post" onsubmit="validateForm()" >
Input1: <input type="text" name="input1"><br/>
Input2: <input type="text" name="input2"><br/>
<input type="submit">
</form>

serialize array returning an empty array

I'm trying to grab some form data in my function but for some reason my fom returns an empty array when i try and run the function .serializeArray() on it. I've checked that to make sure it input element has a name I just can't figure out why this is happening
this is my form
<form id="uploadForm" name="form" action="{{nodeSocketUrl}}/upload?tenant=qa&envelope=true" method="POST" enctype="multipart/form-data" class="forms" style="left:15px">
<fieldset class="units-row">
<h3>Upload A Presentation</h3>
<label for="presentationFileUpload">Select a .ppt, .pptx, .pdf</label>
<input type="file" id="presentationFileUpload" name="presentationFile" onchange="angular.element(this).scope().onFileSelect(this)"/>
<hr>
<input type="submit" id="fileUploadBtn" class="btn btn-primary disabled" value="Upload" ng-click="uploadFile($event)" name="upload">
</fieldset>
</form>
This is my function which I'm hopping to get the form data from
$scope.uploadFile = function(e) {
e.preventDefault();
//$scope.form.preventDefault();
var dCheck = $('input[type="file"]').val();
console.log(e.currentTarget);
var form = $('#uploadForm').serializeArray();
console.log(form);
}
form returns an empty array any help with this would be appreacited
Why not think in pure angular way?
use can use
<input type="file" ng-model="filePath">
And next, get the file name in $scope.filePath

How do I automatically insert a default value into a textarea if no value was entered in by a user?

I have a form with a few textareas in it and I need to figure out a way to automatically insert the word "null" as the textarea values if a user chooses not to include any data in the textarea fields. I would greatly appreciate any one who would be willing to help me out with this. Thank you!
Here's a copy of the code:
<?php
$title = "Add a New Page";
$url = "add";
$metadescription = "Create and publish a new page";
include('/templates/head.php');
echo ('<title>'.$title.'</title>
<meta name="description" content="'.$metadescription.'" />');
include('/templates/meta.php');
echo ('<div id="content">');
include('/page-creator.php');
?>
<h2>Add a New Page</h2>
<form method="post" action="#">
<input type="hidden" name="url" value="null">
<input type="hidden" name="commentform" value="yes">
<h3>Author and Page Information (Required):</h3>
<p><strong>Author Name</strong>: <input style="width:250px;" type="text" name="authorname" value="null"></p>
<hr>
<p><strong>Author URL</strong>: <input style="width:250px;" type="text" name="authorurl" value="null"></p>
<hr>
<p><strong>Page Title</strong>: <input style="width:250px;" type="text" name="title" value="null"></p>
<hr>
<p><strong>Page Date</strong>: <input style="width:250px;" type="text" name="pagedate" value="<?php echo date('D, M d Y, g:ia T'); ?>"></p>
<hr>
<p><strong>Brief Description</strong>: One or two sentences.<br/><br/>
<textarea style="width:95%; height:50px;" name="metadescription">null</textarea></p>
<hr>
<h3>Top Section (Required):</h3>
<p><strong>TOP SECTION CONTENT</strong>: In plain text format (NO HTML) describe the details.<br/><br/>
<textarea style="width:95%; height:100px;" name="topsectioncontent"></textarea></p>
<hr>
<p><strong>TOP SECTION IMAGE</strong>: <input style="width:250px;" type="text" name="topsectionimage"></p>
<hr>
<p><strong>TOP SECTION CODE</strong>: Enter css, html, php or other scripting code.<br/><br/>
<textarea style="width:95%; height:100px;" name="topsectioncode">null</textarea></p>
<hr>
<h3>Middle Section (Optional):</h3>
<p><strong>MIDDLE SECTION CONTENT</strong>: In plain text format (NO HTML) describe the details.<br/><br/>
<textarea style="width:95%; height:100px;" name="middlesectioncontent">null</textarea></p>
<hr>
<p><strong>MIDDLE SECTION IMAGE</strong>: <input style="width:250px;" type="text" name="middlesectionimage" value="null"></p>
<hr>
<p><strong>MIDDLE SECTION CODE</strong>: Enter css, html, php or other scripting code.<br/><br/>
<textarea style="width:95%; height:100px;" name="middlesectioncode">null</textarea></p>
<hr>
<h3>Bottom Section (Optional):</h3>
<p><strong>BOTTOM SECTION CONTENT</strong>: In plain text format (NO HTML) describe the details.<br/><br/>
<textarea style="width:95%; height:100px;" name="bottomsectioncontent">null</textarea></p>
<hr>
<p><strong>BOTTOM SECTION IMAGE</strong>: <input style="width:250px;" type="text" name="bottomsectionimage" value="null"></p>
<hr>
<p><strong>BOTTOM SECTION CODE</strong>: Enter css, html, php or other scripting code.<br/><br/>
<textarea style="width:95%; height:100px;" name="bottomsectioncode">null</textarea></p>
<hr>
<h3>Credits and Footnotes (Optional):</h3>
<p><strong>Ref #1 Name:</strong>: <input style="width:250px;" type="text" name="ref01name" value="null"></p>
<p><strong>Ref #1 URL:</strong>: <input style="width:250px;" type="text" name="ref01url" value="null"></p>
<hr>
<p><strong>Ref #2 Name:</strong>: <input style="width:250px;" type="text" name="ref02name" value="null"></p>
<p><strong>Ref #2 URL:</strong>: <input style="width:250px;" type="text" name="ref02url" value="null"></p>
<hr>
<p><strong>Ref #3 Name:</strong>: <input style="width:250px;" type="text" name="ref03name" value="null"></p>
<p><strong>Ref #3 URL:</strong>: <input style="width:250px;" type="text" name="ref03url" value="null"></p>
<hr>
<input type="submit" value="Publish">
</form>
<?php
include('/templates/footer.php'); ?>
Use a shorthand if:
var myValue = myText.value ? myText.value : 'null';
This is, essentially:
var myValue = function() {
if (myText.value) {
return myText.value;
} else {
return 'null';
}
}
With that said, I don't feel you should include this logic on the client. It may be best if whatever you're sending these values handle this scenario, if you have control over it.
So if you are using jQuery then you would do something like this when they click on the submit button, the return true is there so that it will continue with the submit after this function is run.
$(function() {
$('#submitButton').click(function() {
$('textarea').each(function(element) {
if ($(this).text() === '') {
$(this).text('null');
}
});
return true;
});
});
​
I have a JSFiddle that you can try to see what it does.
JSFiddle
I assume you don't want the word 'null' appearing in the UI. I am also assuming that you are handling the returned values in some sort of server-side script.
Be that the case, I would simply test the length of the values stored in the textareas, and if the length is zero (and remember to check for entered spaces etc. using TRIMs and string cleaning routines) I would simply do (pseudo code):
if (mytextarea1.text.length == 0)mytextarea1.text='null'
if (mytextarea2.text.length == 0)mytextarea2.text='null'
etc.

Save data to localStorage when form is submitted

Is it possible to save data from form to localStorage AND submit the form? I need to submit the form but it would be important to save the values to localStorage also. How can I do this?
Here is the code I have for the form and localStorage, but this doesn't submit the form. It just saves the values.
<label for="server"> Server: </label>
<input type='text' name="server" id="saveServer"/>
<button onclick="save_data()" type="button" value="Save" id="Save" data-theme="a">Save</button>
<script> function save_data()
{ var input = document.getElementById("saveServer");
localStorage.setItem("server", input.value);
var storedValue = localStorage.getItem("server"); }
Sure, but you'll probably want to shake up your approach a bit to call save_data as the form is being submitted:
<form onsubmit="save_data()">
<!-- The rest of your form goes here -->
<button type="button" value="Save" id="Save" data-theme="a">Save</button>
</form>
<script>
function save_data() {
var input = document.getElementById("saveServer");
localStorage.setItem("server", input.value);
var storedValue = localStorage.getItem("server");
// etc..
}
</script>