'Redirect form after submission (Form Action)

I created a form using google apps script editor and I'm trying to open a link to a specific URL once the form is submitted

.html

<form name="submit-to-google-sheet" id="form" action="http://example.com" target="_top" 
onsubmit="myFunction()">

<input type="submit" value="Submit">
</form>

<script>
function myFunction() {
alert("The form was submitted. Please press okay to reload the page");
}
</script>

In this part

action="http://example.com"

I'm supposed to replace the example.com with the page URL where the form is (just to reload the whole page as the alert says) but the form action is not working for some reason. Any help ..

Below are the complete codes as in my dashboard:

Form.html

<!DOCTYPE html>
<html>
<body>
<style>
</style>

<div class="ss-form-container">
<div class="ss-top-of-page">
<div class="ss-form-heading">
<h1 class="ss-form-title" dir="ltr">Test</h1>
<div class="ss-form-desc ss-no-ignore-whitespace" dir="ltr">WELD DATE 
00</div>
<div class="ss-required-asterisk" aria-hidden="true" id="Required">* 
Required</div></div></div><br>

<form name="submit-to-google-sheet" id="form" action="http://example.com" 
target="_top" onsubmit="myFunction()">

<input name="TEXT" type="text" placeholder="text" required>

<input name="email" type="email" placeholder="Email" required>

<div class="ss-q-title">JOINT
<span class="ss-required-asterisk" aria-hidden="true">*</span></div>

<? var innerHTML= createInnerHTML(); ?>  
<select name="JOINT" id="JOINT" aria-label="JOINT" aria-required="true" 
required="">
<option value=""></option>
<? innerHTML.forEach(function(option) { ?>
<option value="<?= option.value ?>"><?= option.text ?></option>
<? }); ?>
</select>

<input type="submit" value="Submit" name="submit" id="Submit">
</form>

<script>
function myFunction() {
alert("The form was submitted. Please press okay to reload the page");
}
</script>

<script>
const scriptURL = 'https://script.google.com/macros/s/AKfycbwTGqZqLTAsOpSweMn0xgHP0sOJPsFg5ZShC1HqzVoDoNi5h5Y/exec'
const form = document.forms['submit-to-google-sheet']
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, { method: 'POST', body: new FormData(form)})
  .then(response => console.log('Success!', response))
  .catch(error => console.error('Error!', error.message))
})
</script>

</div>
</body>
</html>

Code.gs

function doGet() {
return HtmlService.createTemplateFromFile('Form.html')
    .evaluate() // evaluate MUST come before setting the Sandbox mode
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}

var sheetName = 'Sheet1'
var scriptProp = PropertiesService.getScriptProperties()


function doPost (e) {
var lock = LockService.getScriptLock()
lock.tryLock(10000)

 try {
 var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
 var sheet = doc.getSheetByName(sheetName)

 var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues() 
 [0]
 var nextRow = sheet.getLastRow() + 1

 var newRow = headers.map(function(header) {
  return header === 'timestamp' ? new Date() : e.parameter[header]
 })

 sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

 return ContentService
  .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow 
 }))
  .setMimeType(ContentService.MimeType.JSON)
 }

 catch (e) {
 return ContentService
  .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
  .setMimeType(ContentService.MimeType.JSON)
  }

finally {
lock.releaseLock()
}
}


function createInnerHTML() {
var ss = SpreadsheetApp.getActive();
var names = ss.getSheetByName("CHOICES");
var namesValues = names.getRange(2,2,names.getLastRow()-1).getValues(); 
var innerHTML = [];
for (var i=0;i<namesValues.length;i++){
innerHTML.push({value:''+ namesValues[i][0], text:namesValues[i][0]});
};
return innerHTML;
}


Solution 1:[1]

Assuming that you want the following actions to happen when the form is submitted:

  • A new row is appended in Sheet1 of your spreadsheet.
  • You get redirected to the form.

You can accomplish this by following these steps:

(1) Remove the following script from your html:

<script>
const scriptURL = 'https://script.google.com/macros/s/AKfycbwTGqZqLTAsOpSweMn0xgHP0sOJPsFg5ZShC1HqzVoDoNi5h5Y/exec'
const form = document.forms['submit-to-google-sheet']
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, { method: 'POST', body: new FormData(form)})
  .then(response => console.log('Success!', response))
  .catch(error => console.error('Error!', error.message))
})
</script>

(2) Change this line in your html:

<form name="submit-to-google-sheet" id="form" action="http://example.com" target="_top" 
onsubmit="myFunction()">

To this one:

<form name="submit-to-google-sheet" id="form" method="POST" action="https://script.google.com/macros/s/AKfycbwTGqZqLTAsOpSweMn0xgHP0sOJPsFg5ZShC1HqzVoDoNi5h5Y/exec" target="_top" onsubmit="myFunction()">

(3) Change this in your Code.gs:

 return ContentService
  .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow 
 }))
  .setMimeType(ContentService.MimeType.JSON)

To this:

return doGet();

So the try block in doPost would be like this:

try {
  var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'));
  var sheet = doc.getSheetByName(sheetName);

  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
  var nextRow = sheet.getLastRow() + 1;

  var newRow = headers.map(function(header) {
    return header === 'timestamp' ? new Date() : e.parameter[header]
  })

  sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])

  return doGet();
}

In this case, doPost returns doGet, so Form.html gets loaded after the previous form data is submitted to the spreadsheet.

Update

In case you want to redirect to another URL, you can do the following.

  • Add an onsubmit trigger that runs a function handleFormSubmit that receives the form as a parameter (this). To do that, change this:
<form name="submit-to-google-sheet" id="form" action="http://example.com" target="_top" onsubmit="myFunction()">

To this:

  <form name="submit-to-google-sheet" id="form" action="http://example.com" 
  target="_top" onsubmit="handleFormSubmit(this)">
  • Next, the function handleFormSubmit calls a server-side function called addData, and passes the form to it as a parameter. So add this script in your HTML:
<script>
  function handleFormSubmit(formObject) {
    google.script.run.addData(formObject);
  }
</script>

Finally, addData (previously doPost) receives the form object as parameter:

function addData(data) {
var lock = LockService.getScriptLock()
lock.tryLock(10000)

 try {
   var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
   var sheet = doc.getSheetByName(sheetName)

   var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
   var nextRow = sheet.getLastRow() + 1

   var newRow = headers.map(function(header) {
     return header === 'timestamp' ? new Date() : data[header]
   })

   sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])
 }

 catch (e) {
 return ContentService
  .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
  .setMimeType(ContentService.MimeType.JSON)
  }

finally {
lock.releaseLock()
}
}

I hope this is of any help.

Solution 2:[2]

You can use prevent default on the form and open a new window using JS method

window.open()

This will not work on StackOverflow because of safety reasons.

document.getElementById('Form').addEventListener('submit', function(evt){
    evt.preventDefault();
    
    
    window.open("http://www.example.com", "_top")
})
<form id = "Form">


<input type="submit" value="Submit">
</form>

Solution 3:[3]

Your code is working fine. form is being submitted to provided action.

<form name="submit-to-google-sheet" id="form" action="http://example.com" target="_top" onsubmit="myFunction()">
    <input type="submit" value="Submit">
</form>

and js part:

function myFunction() {
    alert("The form was submitted. Please press okay to reload the page");
}

Check fiddle: http://jsfiddle.net/cm59koat/1/

Solution 4:[4]

Okay everyone, I tried the below code and worked for me, Keep everything in the question as it is but change this part only:

<script> const scriptURL = 'Script URL'
const form = document.forms['submit-to-google-sheet']
form.addEventListener('submit', e => { e.preventDefault()
window.open(After submit URL)
fetch(scriptURL, { method: 'POST', body: new FormData(form)})
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message)) })
</script>

This will keep the form posting to the linked sheet as well as redirect your form to the added URL after submit

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Ahmed Gaafer
Solution 3 Waseem Ansar
Solution 4 Mahmoud Bayoumi