HtmlService Spreadsheet form refresh - google-apps-script

I have a form ModalForm on a Google Sheet that inserts rows into the sheet. It's been working fine for months. Starting last week after submitting the form the form disappears and doesn't re-display. I'm not sure why. It executes the insert into the spreadsheet fine. I just never get the form back to insert the next record.
In my Index file, the form code:
<form id="myReceiveForm" name="receive" onsubmit="writeLine()">
Scanner Name : <input id="user" name="user" type="text" required /> <br> <br>
Reference Number: <input id="reference" name="reference" type="text" required /> <br> <br>
Location: <input id="location" name="location" type="text" pattern="[A-Z]{1,3}\-[A-Z]{1,2}\-\d{1,3}\-\d{1,2}" title="Location not in correct format." required/>
<button type="button" value="change" onclick="changeLocation()" >Change Location</button><br> <br>
Product SKU: <input id="sku" name="sku" type="text" value="" autofocus /> <br> <br>
<input type="submit" value="Submit" >
</form>
<script type="text/javascript">
function onSuccess() {
document.getElementById("sku").value = '';
document.getElementById("sku").focus();
return false;
}
function onFailureM(error) {
alert("Invalid Sku");
//alert("SKU" + document.getElementById("sku ").value +" doesn't exist.");
document.getElementById("sku").value = '';
document.getElementById("sku").focus();
}
window.writeLine = function () {
google.script.run
.withSuccessHandler(onSuccess)
.withFailureHandler(onFailureM)
.appendRowstoSheet(document.forms[0]);
}
</script>
In My .gs file:
function openReceiving() {
var html = HtmlService.createHtmlOutputFromFile('index');
SpreadsheetApp.getUi().showModalDialog(html, '3PL RECEIVING');

Remove onsubmit="writeLine()" from the upper form tag. Change the submit button:
<input type="submit" value="Submit" >
to a regular button with an event:
<input type="button" value="Submit" onmouseup="writeLine()">
This should fix the problem. On Nov. 12th, 2015 Google migrated to IFRAME mode.
All new scripts will default to IFRAME sandbox mode unless NATIVE mode is explicitly specified.
Google Apps Script Sunset Scedule
This is what probably caused your problem. The form submit causes a form tag to disappear. This is expected behavior that has been in place for a long time in regular HTML. But for a long time, HTML Service overrode that behavior. Now, IFRAME mode is more like regular HTML behavior.
In the SKU input field, try adding an onchange attribute if you need the form to submit after the last field is updated:
<input id="sku" name="sku" type="text" value="" autofocus onchange="writeLine()"/>
onchange Event - Reference information
List of all the events

Related

Google Script HTML form submission

In google sheets I created a menu to add a new employee. It opens a modalDialog using html file (NewEmployee.html) that has a form inside collecting name, starting date, radio buttons (2) and salary (per hour).
HTML Code:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function closeForm(){
google.script.host.close();};
function submitForm(){
google.script.run.getInfoFromSubmitForm(document.getElementById("employeeForm"));};
</script>
</head>
<style type="text/css">
.submit-button{
float: right;}
.cancel-button{
float: left;}
</style>
<body>
<div id="myForm">
<form id="employeeForm" class="form">
<label for="employeeName">Employee Name  </label>
<input
type="text"
id="employeeName"
name="employeeName"
employeeName="employeeName"
placeholder="This will also be the name of the Sheet"
style="width: 230px;"><br><br>
<label for="date">Please select start Date    </label>
<input type="date" id="date" name="date"><br><br>
<label for="employeeType">Please Select Employee Type</label><br>
<input type="radio" id="W2" name="employeeType" value="W2">
<label for="W2">W2</label><br>
<input type="radio" id="W9" name="employeeType" value="W9">
<label for="W9">W9</label><br><br>
<label for="salary">Please enter the Salary(per hour)  </label>
<input type="text" id="salary" name="salary" aria-required="true"><br><br>
<input type="button" class="cancel-button" value="Cancel" onclick="closeForm()">
<input type="button" class="submit-button" value="Submit Form" onclick="submitForm();">
</form>
</div>
</body>
</html>
Menu Code:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Driver Menu')
.addItem('Add Employee', 'showNewEmployeeDialog')
.addToUi();`
};
function handling submission:
function showNewEmployeeDialog() {
var widget = HtmlService.createHtmlOutputFromFile("DatePicker.html");
SpreadsheetApp.getUi().showModalDialog(widget, "Enter Employee Information");
}
const getInfoFromSubmitForm = (form) => {
return form;
}
When I click on menu selection, it opens the modalDialog with all fields visible, but script finishes running. I struggle to collect the info and pass it to the function that would store it as object, and that object would be accessible by other functions in the app script (probably global object declaration, but I need it to be cleared, before it updated, so the new employee info overrides it.)
I think, I'm missing proper onSubmit function and/or eventListener.
Goal is to continue running the script until the form is submitted, make sure all inputs are filled and at least one radio button is clicked. Then send the object {name: value, date: value, employeeType: value (based on which radio button is clicked), and salary value. Once the form is submitted, the dialog closes and global object or function should return the object when function is called.

HTML input validation happens after button onClick is triggered

I have a simple form and the problem is that the validation happens after the click event is registered, thus triggering the doSomething() function. I would like the email validation to stop the user from submitting the form so that the function will not be triggered. How would I do that?
<form>
<input type="email" placeholder="your email here" required/>
<button type="submit" onClick="doSomething()">Submit</button>
</form>
<script>
function doSomething(){
// gets triggered even when the email does not pass validation
console.log('Doing work..');
}
</script>
JSFiddle
You could use the onSubmit attribute in the form, which will only call your function when all fields are validated.
<form onSubmit="doSomething()">
<input type="email" placeholder="your email here" required/>
<input type="submit"/>
</form>
<script>
function doSomething(){
// gets triggered even when the email does not pass validation
console.log('Doing work..');
}
</script>
View this question to understand how to stop the form from submitting.
Thanks,

Form submit to a text field

How to make a form that submit to a text field below
<form action="">
Text: <input type="text" name="firstname">
<input type="submit" value="Submit"><br><br>
Post text: <input type="text" name="firstname">
</form>
You will need to use JavaScript for that:
<script>
function submitted() {
formValue = document.getElementsByName("firstname")[0].value;
document.getElementsByName("firstname")[1].setAttribute("value", formValue); // Copy the value
return false;
}
</script>
<form onsubmit="return submitted()"> <!-- Call submitted when the form is submitted -->
Text: <input type="text" name="firstname">
<input type="submit" value="Submit"><br><br> Post text: <input type="text" name="firstname">
</form>
However, there is no need for a form for that. The onsubmit attribute is mostly used for when you want to alert the user that the form was submitted; the actual submission is done on the server through PHP or something else, and not through JavaScript (since the user has access to the JavaScript code and could change the input checking process as he wishes). Here you could simply have something like this:
<script>
function submitted() {
formValue = document.getElementById("firstname").value;
document.getElementById("postFirstname").setAttribute("value", formValue); // Copy the value
}
</script>
Text: <input type="text" id="firstname">
<button onclick="submitted()">Submit</button>
<br><br> Post text: <input type="text" id="postFirstname">

HTML 5 pattern not working for onclick event of button

In a page, for getting field values I didn't use form tag, instead used Anchor tag's click event to get the values and used AJAX call to pass it to server.
Later tried out the HTML 5 pattern validation, it didn't work out; after so much try added form tag and then modified "anchor" to "button", then it worked.
Old
<div id="div1">
<input type="text" id="message" pattern="[a-zA-Z]{3}" required title="Enter valid Station" />
<a id="add" onclick="addMessage();">Add</a>
</div>
New
<form id="addMessage">
<div id="div1">
<input type="text" id="message" pattern="[a-zA-Z]{3}" required title="Enter valid Station" />
<button id="add">Add</button>
</div>
</form>
Is using a form tag and form submission the only way to trigger Pattern validation or are there any workarounds?
There's a nice overview of constraint validation in HTML5 on HTML5Rocks.
You can manually validate fields by calling the checkValidity() method on the DOM element in JavaScript:
document.getElementById('add').addEventListener('click', function() {
if (document.getElementById('message').checkValidity()) {
window.alert('valid station name');
// addMessage();
} else {
window.alert('invalid station name!');
}
});
<div id="div1">
<label>
Station
<input type="text" id="message" pattern="[a-zA-Z]{3}" required title="Enter valid Station" maxlength="3">
</label>
<a id="add" role="button">Add</a>
</div>
And also for reference: HTMLInputElement

Do Not Load Page After Form Submit

I have created a basic HTML contact form using cgimail and everything works, but I can't get it to keep from redirecting somewhere after the form is submitted. I'm trying to instead use a bootstrap alert at the top of the page.
How do I get the form to submit, then keep it from redirecting?
here's the code:
<form method="post" action="/cgi-bin/cgiemail/forms/email.txt">
<fieldset>
<h2 id="contact-header">Contact</h2>
<label>Name:</label>
<input type="text" name="yourname" placeholder="" autofocus>
<label>Email Address:</label>
<input type="email" name="email" value="" placeholder="">
<label>Phone:</label>
<input type="tel" name="phone" value="" placeholder="">
<label>Message:</label>
<textarea name="message" rows="2"></textarea>
<br>
<button type="submit" id="formSubmit" class="btn">Send</button>
<input type="hidden" name="success" value="">
</fieldset>
</form>
Thanks,
Ryan
The "action" attribute in your form is telling it to send the browser over to that email.txt, which would then have control over whether or not to redirect you to another page. By default it would at least redirect you to the email.txt page for the post, but odds are cgi is doing extra stuff when posting to that page.
Using jQuery AJAX, you can do the following (this code skips error checking):
$('form').submit(function() {
var data = { };
data.yourname = $(this).find('input[name="yourname"]').val();
data.message = $(this).find('textarea[name="message"]').val();
// do the same as above for each form field.
$.post("/cgi-bin/cgiemail/forms/email.txt", data, function() {
//add the alert to the form.
$('body').prepend('div class="alert">Success!</div>');
});
return false;
});
You have two straight-forward choices. You can use jQuery and its forms plugin to turn this into an ajax operation or you can roll your own equivalent. It would look something like this (using jQuery):
$('form').submit(function() {
... get all values.
... ajax post the values to the server.
return false;
});
If you're using jQuery, then you could try cancelling the submit event. First give your form an id
HTML:
<form id="myform" ...
JavaScript:
$('#myform').on('submit', function(e) {
e.preventDefault();
$.ajax({
url: '/cgi-bin/cgiemail/forms/email.txt',
type: 'post',
data: $(this).serialize()
});
return false;
});