levinunnink / html-form-to-google-sheet

How to submit HTML forms to Google Sheets. (Updated for 2024 Script Editor)
https://sheetmonkey.io
MIT License
796 stars 147 forks source link

Beginner trying to redirect users to an HTML page instead of Appscript JSON result #13

Open elmoumenyassine opened 1 year ago

elmoumenyassine commented 1 year ago

Hello Author,

I am a beginner and i didn't understand the note saying :

" If you want to intercept the submit event so the user isn't redirected to the webapp, you can do this by attaching a JavaScript event listener to the form submission and creating the POST request yourself "

I dont want the user to have an "https://script.googleusercontent.com/macros/echo?user_content_key=....etc"

and a JSON response like this :

image

The JS in codepen is the following. I don't really understand were to put it. Can you help me please ?

Before all i have to say that i was more a lowcoder (with appsheet and Excel VBA)

Thank you by advance

window.addEventListener("load", function() { const form = document.getElementById('my-form'); form.addEventListener("submit", function(e) { e.preventDefault(); const data = new FormData(form); const action = e.target.action; fetch(action, { method: 'POST', body: data, }) .then(() => { alert("Success!"); }) }); });

(i created a Github account just because of this. A great opportunity :) )

El Moumen Y.

@levinunnink @meandavejustice @shadichy

shadichy commented 1 year ago

Put it in your website's source code

elmoumenyassine commented 1 year ago

@shadichy thank you for the reply i am in this moment fighting with it

I dont see why it doesnt work

I ll make an other html file with form including the appscript link for POST method and add the JS code at the end en of the body with

elmoumenyassine commented 1 year ago

@shadichy @levinunnink @meandavejustice

I just tried it and :

  1. The data is transfered
  2. The form stay static (the data remains written on the form (as if it were not sent)
  3. [I am using Google Chrome] but i have the same result in OPERA/SAFARI/FIREFOX/EDGE

For information, i am using bootstrap, it may change something, i don't know !

Here is the code source joined

[Uploading JS-ISSUE.zip…]()

elmoumenyassine commented 1 year ago

This one doesn't work

`

`

Nor this one

`

`
shadichy commented 1 year ago

@elmoumenyassine First, assign an id to your form (<form id="yourFormID" ...) Next, add

window.addEventListener("DOMContentLoaded", function() { // 'window.onload = function...' also works 
  const yourForm = document.getElementById("yourFormID");
  yourForm.addEventListener("submit", function(e) { // 'yourForm.onsubmit = function...` also works too
    e.preventDefault(); 
    const data = new FormData(yourForm); 
    const action = e.target.action; 
    fetch(action, { 
      method: 'POST', 
      body: data, 
    }).then((response) => {
      response.json();
    }).then((data) => {
      if (data.result == "success") {
        // finished, you can do whatever you want here
        alert("Success!")
      }
    })
  })
});

to your js source or HTML source (inside script tag)

shadichy commented 1 year ago

@levinunnink I think you should close this now

netihj commented 1 year ago

I am also looking for the solution. Above responses are not working.

shadichy commented 1 year ago

I am also looking for the solution. Above responses are not working.

Detail please

brockTnL commented 1 year ago

@shadichy First of all, thanks for your time and comments. The code succeeds (ie., I get the Success alert) but only 1 of the two values I need are copied to the sheet. Here's my code:

<h4 style="text-align: center;">Was this page helpful?</h4>

<form action="https://script.google.com/macros/s/AKfycbwZN0sQ_2UDz6j4m3xkTObIieiMIxo3QyI22y_OK-j4jj5wvEhI0PS_f6YZ4_Iqen2Q4A/exec" id="my-form" method="POST">

<h4 style="text-align: center;">
<input class="btn btn-success" name="Helpful?" onclick="myFunction()" type="submit" value="Yes" /> 
<input class="btn btn-danger" name="Helpful?" onclick="myFunction()" type="submit" value="No" /></h4>

<input id="url" name="URL" style="display:none;" type="url" value="" />&nbsp;</form>

<script>
function myFunction() {
  var currentLocation = window.location;
  document.getElementById('url').value = currentLocation;
}

window.addEventListener("DOMContentLoaded", function() {
  const yourForm = document.getElementById('my-form');
  yourForm.addEventListener("submit", function(e) {
    e.preventDefault();
    const data = new FormData(yourForm);
    const action = e.target.action;
    fetch(action, {
      method: 'POST',
      body: data,
    })
    .then(() => {
      alert("Thanks for your feedback!");
    })
  });
});
</script>

In my spreadsheet I have three columns: date (automatically completed by the App); URL (the value is dynamically identified using the function above); and Helpful? (either yes or no depending on which input the user clicks on). The Helpful? input isn't being posted.

Any thoughts?

shadichy commented 1 year ago

Any thoughts?

Modify your google appscript, the problem is there, not this

asd1495 commented 1 year ago

I have the same problem and none of the possible solutions is working for me, everytime the contact form is submited it redirects to script.googleusercontent.com/

ivarley commented 1 year ago

To chime in on what @asd1495 said above, I can definitely redirect to another page. The issue is that it doesn't really redirect; it displays my page, but the URL still says script.googleusercontent.com/... . And this remains even as you click other links (which itself seems like a security problem). If you hit refresh, it resubmits the original form.

I'm a little confused about the general lack of solutions to this problem; I've been hunting for a while and every option seems to not work. How is anyone even using this without being able to send the user on to another page, rather than just showing them a JSON response?

shadichy commented 1 year ago

To chime in on what @asd1495 said above, I can definitely redirect to another page. The issue is that it doesn't really redirect; it displays my page, but the URL still says script.googleusercontent.com/... . And this remains even as you click other links (which itself seems like a security problem). If you hit refresh, it resubmits the original form.

I'm a little confused about the general lack of solutions to this problem; I've been hunting for a while and every option seems to not work. How is anyone even using this without being able to send the user on to another page, rather than just showing them a JSON response?

redirect it to a blank iframe

ivarley commented 1 year ago

redirect it to a blank iframe

Thanks. I'm not sure I understand how I'd do that. Right now, I'm using this code after inserting the spreadsheet rows:

return HtmlService.createHtmlOutputFromFile('my-response-page');

And the contents of my-response-page (in the Google Apps Script project) is simply:

<meta http-equiv="refresh" content="0 URL=https://my-redirect-url" />

It does correctly redirect to that resulting page, but inside a frame, and nothing I do inside that frame seems to be able to break out or change the top URL. For example, I put this script in the head of the page:

    <script type = "text/javascript">
        <!--
            parent.top.location.replace("https://my-redirect-url");
        //-->
     </script>

But no change.

The frame page source is as follows:

<!doctype html>

<html>

<head>

<meta name="chromevox" content-script="no">

<link rel="stylesheet" href="[https://fonts.googleapis.com/icon?family=Material+Icons](https://fonts.googleapis.com/icon?family=Material+Icons)" nonce="RqOmXmADPbq3uHE1af37VA"><link rel="stylesheet" href="[/static/macros/client/css/732732727-mae_html_css_ltr.css](https://script.google.com/static/macros/client/css/732732727-mae_html_css_ltr.css)">

<script type="text/javascript" src="[/static/macros/client/js/2417134270-warden_bin_i18n_warden.js](https://script.google.com/static/macros/client/js/2417134270-warden_bin_i18n_warden.js)" nonce="Gv2h9ntjGYcMSO2hssxDKg"></script>

</head>

<body>

<iframe id="sandboxFrame" allow="accelerometer *; ambient-light-sensor *; autoplay *; camera *; clipboard-read *; clipboard-write *; encrypted-media *; fullscreen *; geolocation *; gyroscope *; magnetometer *; microphone *; midi *; payment *; picture-in-picture *; screen-wake-lock *; speaker *; sync-xhr *; usb *; web-share *; vibrate *; vr *" sandbox="allow-downloads allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-top-navigation-by-user-activation">

</iframe>

<script type="text/javascript" nonce="Gv2h9ntjGYcMSO2hssxDKg">

(function() {

var el = document.getElementById('sandboxFrame');

el.onload = function() {

goog.script.init("\x7b\x22functionNames\x22:\x5b\x22initialSetup\x22,\x22doPost\x22\x5d,\x22sandboxMode\x22:\x22IFRAME_SANDBOX\x22,\x22callbackTimeout\x22:1830000,\x22deploymentId\x22:\x22AKfycbxSX3K0Pzc8A9ZGCu-y5FSuJTyFvHXKRtx3bfXkOqfuyhEK5yyxkPC6UxO3ZgD_P5Uc\x22,\x22eei\x22:\x22\x22,\x22sandboxHost\x22:\x22https:\/\/n-zdwlluwzapjau3ymnlnyhkxuj26sbhzgdck3gfq-0lu-script.googleusercontent.com\x22,\x22clientSideProperties\x22:\x7b\x22google.script.sandbox.mode\x22:\x22IFRAME_SANDBOX\x22,\x22google.script.host.origin\x22:\x22https:\/\/docs.google.com\x22\x7d,\x22actionPrefix\x22:\x22\/a\/mycompany\/macros\/s\/AKfycbxSX3K0Pzc8A9ZGCu-y5FSuJTyFvHXKRtx3bfXkOqfuyhEK5yyxkPC6UxO3ZgD_P5Uc\x22,\x22userHtml\x22:\x22\x3cmeta http-equiv\x3d\\\x22refresh\\\x22 content\x3d\\\x220 URL\x3dhttps:\/\/my-redirect-url\/forms\/artifact-added\\\x22 \/\x3e\x22,\x22ncc\x22:\x22\x7b\\\x22awhs\\\x22:true\x7d\x22\x7d", "AJuLMu3nAN218RJlZ56jrm_zEgs4CrSPLg:1677512428504", undefined, false , true , "true", "https:\/\/n-zdwlluwzapjau3ymnlnyhkxuj26sbhzgdck3gfq-0lu-script.googleusercontent.com");}

el.src = 'https:\/\/n-zdwlluwzapjau3ymnlnyhkxuj26sbhzgdck3gfq-0lu-script.googleusercontent.com\/userCodeAppPanel';

}());

</script>

</body>

</html>

Could this be related? https://developers.google.com/apps-script/reference/html/x-frame-options-mode

shadichy commented 1 year ago

hmm

shadichy commented 1 year ago

i've managed to deal with that before, just, I might have to find it =))

rss2nse commented 11 months ago

Did anyone find solution for the redirect to custom url instead of apps script return?

shadichy commented 11 months ago

Did anyone find solution for the redirect to custom url instead of apps script return?

JS fetch

eligiofonseca commented 7 months ago

https://codepen.io/levinunnink-the-bashful/pen/YzxPyoG?editors=1010 Using this method. I find that it all works IF i remove the action value ie <form action=https://script.google.com/macros/s/1234blah

Using this method: https://github.com/levinunnink/html-form-to-google-sheet/issues/13#issuecomment-1238973562 I could not get it to work in lieu of option 1 above.

Anyone have a solution? I would like to redirect to a success.html file i created on success POST, instead of the json page https://script.googleusercontent.com/macros/echo

rss2nse commented 7 months ago

Don't make any changes in apps script, but I modified in my html code like this and after alert it redirects to home page

$('form').each(function() { this.reset() });

    document.getElementById("myForm").onsubmit = function (e) {
        e.preventDefault();
        submitForm();
    };

    function submitForm() {
         document.getElementById("clk").style.display = "none";
         document.getElementById("clk").disabled = true;
document.getElementById("clk").innerHTML = "Loading";

        var formData = new FormData(document.getElementById("myForm"));
        fetch('https://script.google.com/macros/s/{YOUR_SCRIPT_ID}/exec', {
            method: 'POST',
            body: formData,
        })
        .then(function(response) {
            // Handle successful form submission
            if (response.ok) {
                document.getElementById("clk").disabled = false;
    document.getElementById("clk").innerHTML = "Submit";
    window.location.href = 'index.html';

// Redirect to the home page
            }
        })
        .catch(function(error) {
            console.error('Error:', error);
        });

    }