javascripthtmlgoogle-apps-scriptgoogle-formsonsubmit

Google-Forms EventListener


My goal is that on submitting the form a paypal page would open, but nothing happened so I added the logs which didn't log anything.

The first console logs of my code appear, but the ones inside of the function onSubmit() don't appear, but I also know that the function is running, because google.script.run.processForm() is getting called and there is also no error message.

console.log("Page loaded, preparing to submit form");

window.onload = function() {
  var form = document.querySelector('form');
  console.log(form)
  form.addEventListener('submit', onSubmit); // Listen for the submit event
}

function onSubmit(event) {
  event.preventDefault();

  alert("onSubmit() was called!");
  console.log("Form submitted");

  google.script.run
    .withSuccessHandler(function(url) {
      console.log("Redirecting to:", url);

      if (typeof url === "string" && url.startsWith("https://")) {
        window.open(url, "_self");
      } else {
        alert("Error: Invalid PayPal link.");
      }
    })
    .processForm();
}
<form>
  <iframe src="https://docs.google.com/forms/d/e/(private)/viewform?embedded=true" width="640" height="1169" frameborder="0" marginheight="0" marginwidth="0">Wird geladen…</iframe>
</form>

Solution

  • The fact that the alert is not shown proves that your program never reaches the point where the alert is supposed to happen. Therefore at the end of the exercise, .onSubmit is not called.

    Putting your iframe aside for a second, this is possible in cases such as when var form = document.querySelector('form'); retrieved some other form than the one you expected. Imagine an HTML with two forms and you want to attach a submit event handler to the second form. querySelector('form') is not very specific. See this snippet:

    document.querySelector('form').addEventListener('submit', function(evt) {
        evt.preventDefault();
        alert('The form submitted');
    });
    <form>Form1 <button>Lick me to continue</button></form>
    <form>Form2 <button>Lick me to continue</button></form>

    You can see that your selector found the first form and attached an event to it. If you intended to attach the event to the second form, then it will not work as you intended.

    Now, with the iframe in play, your page inside the iframe may have a form inside of it, but that's only submitting the form inside the page of the iframe, but not the form that encapsulates the iframe in the outer page. If you intend to submit the form that includes the iframe when the iframe was submitted, you can do something like below:

    myIframe.addEventListener('load', function() {
        if (myIframe === 'some/path/here') {
            myIframe.parentNode.submit();
        }
    });
    

    let param = 1;
    let firstLoad = true;
    function changeSrc() {
        document.getElementById("myframe").src = `https://www.google.com?param=${param++}`;
    }
    
    document.getElementById("myform").addEventListener("submit", function(evt) {
        evt.preventDefault();
        alert("loaded " + document.getElementById("myframe").src + " and submit event triggered!");
    });
    
    document.getElementById("myframe").addEventListener("load", function() {
        if (!firstLoad) document.querySelector("#myform button").click();
        firstLoad = false;
    });
    iframe {
        width: 500px;
        height: 500px;
    }
    <form id="myform">
        <button style="display: none;">Submit</button>
        <input type="button" value="Change Source" onclick="changeSrc(event)">
        <br>
        <iframe id="myframe" src="https://www.google.com"></iframe>
    </form>

    I also tested by triggering the submit() of the form on iframe load, but that did not detect the submit, perhaps because it was not humanly triggered. But if you do so via auto-clicking the submit button, then it works.