0

The majority of the Add-on is good but whenever I hit enter (which is, in my opinion, the most common way to submit a form, for example, a login form), but all it does is blank out.

I've tried linking the script with a onkeydown like so:

<div onkeydown="handle(event)">blagh blagh blagh</div>

but I still get the same results:

<html>
<form id='myForm' style="font-family:Georgia;">

<table>
<tr><td><h2>Enter your Password</h2></td></tr>
<tr><td><p>DO NOT HIT ENTER ON YOUR KEYBOARD!!!!!</p></td></tr>
<tr><td><input name='password' type='password' value="" onkeypress="handle(event)"></td></tr>
<tr><td><div id="submitbuttcontainer"><img id="submitloader" style="display:none;" src='https://lh6.googleusercontent.com/-S87nMBe6KWE/TuB9dR48F0I/AAAAAAAAByQ/0Z96LirzDqg/s27/load.gif' /><input id="submitbutt" type='button' onclick='showWorking();google.script.run.withSuccessHandler(onSuccess).decodeForRequest(document.getElementById("myForm"));' name="Submit" value="Submit"></div></td></tr>
</table>

</form>
<script>
function onSuccess(obj) {
  document.getElementById('submitbutt').style.display="block";
  document.getElementById('submitloader').style.display="none";
  if(obj.status == 'success') {
    google.script.host.closeDialog();
    browser.msgbox('Access Granted', browser.buttons.OK)
   }
   else { 
    browser.msgbox('ALERT!!','!OOF!','Incorrect Password. Please retry', browser.buttons.OK);
   }
}
function showWorking() {
  document.getElementById('submitbutt').style.display="none";
  document.getElementById('submitloader').style.display="block";
}

function handle(e){
        if(e.keyCode === 13)
document.getElementById('submitbuttcontainer').click();
        }
</script>
</html>

All I'm trying to do is get the form to submit when I hit enter and not blank out. I always hit enter to submit a form but in this case all it does is blank out the form and all I have is whiteness.

Here's the link for the complete source code (don't know if this will work because I'm in a school district):

https://script.google.com/a/bcsdschools.net/d/1_YUx4ZP3qEWVcFMc-MvfEYX2S34r7-b4M0iRlE_JQa81T3ZubN5OeISa/edit)

WhiplashGamz
  • 69
  • 1
  • 11

2 Answers2

6

Problem

Hitting enter key results in form submission (which is explicitly forbidden in Apps Script due to its client-to-server communication implementation).


Solution 1 - handle inputs individually

Add preventDefault() to a keydown event if key is enter (btw, keypress event is deprecated, see reference on MDN, use the keydown / keyup instead):

var ENTER_CODE = 13;

function handle(e) {
  if(e.keyCode === ENTER_CODE) {
    e.preventDefault();
    document.getElementById('submitbuttcontainer').click();
  }
}

Solution 2 - handle form submit

You can listen for a submit event on your form instead and invoke preventDefault() as the only statement in event handler or handle form submission at the same time if you expect form to be submitted on enter key hit:

//assumption: form is initiated elsewhere in code;
form.addEventListener('submit', (event) => {
  event.preventDefault();

  //handle submission;
});

You can also prevent all forms from being submitted to make the setup flexible:

(() => {
  const { forms } = document;

  Object.values(forms).forEach(
    form => form.addEventListener("submit", (e) => e.preventDefault())
  );
})();

Or, alternatively, use event delegation and register one listener on the document since the event bubbles up:

document.addEventListener("submit", (e) => e.preventDefault());

Suggestion

Please, use addEventListener instead of on[event name here] attributes. This way is much more flexible and has the benefit of being concise and easy for others to read.

References

  1. Handling forms in Apps Script guide
  2. Why use addEventListener? MDN reference
  • how did i not know that "keypress" is deprecated >:( – WhiplashGamz Sep 09 '19 at 11:16
  • Zachary, it is actually deprecated for quite some time, but this isn't obvious unless you use MDN or specifications themselves for reference when needed. For example, w3schools lists it without any warning of deprecation – Oleg Valter is with Ukraine Sep 09 '19 at 20:26
  • Btw, have you been able to successfully solve the issue? Both mine and Cooper's answers boil down to the use of `preventDefault()` added as first statement in `submit` event handler – Oleg Valter is with Ukraine Sep 09 '19 at 20:30
  • @ZacharyCross - huh, glad to know you are still here and fixed it :) The easiest way is to use the solution #2 and just overwrite all "submit" events - they are pretty much useless in GAS as you can't actually "submit" forms – Oleg Valter is with Ukraine Oct 08 '20 at 22:58
  • and I just started learning about addEventListener and I kinda wish I would have used them instead. cause you are right about them being more flexable – WhiplashGamz Oct 15 '20 at 18:58
  • @ZacharyCross - well, once you enter frameworks territory (i.e. Angular), you will suddenly find out that you are using a version of what you did before (under the hood everything is different, though). – Oleg Valter is with Ukraine Oct 16 '20 at 05:53
2

I wanted to try to give you a complete answer, but I have to admit that I may know less about event handlers than you. But this seems to work for me.

aq4.html:

<html>
  <head>
    <script>
      window.onload=function() {
        preventFormSubmit1();
      }
      
      function preventFormSubmit1() {
        console.log('preventFormSubmit1');
        var form=document.forms['myForm'];
        form.addEventListener('submit',function(e) {
          e.preventDefault();
        });
      }
           
      function handleFormSubmit(formObject) {
        console.log('handleFormSubmit');
        var first=document.forms['myForm']['first'].value;
        var last=document.forms['myForm']['last'].value
        var sheet=document.forms['myForm']['sheet'].value;
        console.log('%s,%s,%s',first,last,sheet);
        if(first.length>0 && last.length>0 && sheet.length>0) {
          google.script.run
          .withSuccessHandler(function(msg){
            var div=document.getElementById('output');
            div.innerHTML=msg;  
            var inputs=document.querySelectorAll('input[type=text]');
            inputs[0].focus();
            for(var i=0;i<inputs.length;i++) {
              inputs[i].value='';
            }
          })
          .processForm(formObject);
        }else{
          alert("Invalid or Incomplete Data");
        }
      }
     
      console.log("MyCode");
    </script>
  </head>
  <body>
     <form id="myForm" onsubmit="handleFormSubmit(this)">
      <input type="text" name="first" /> First<br />
      <input type="text" name="last" /> Last<br />
      <select name="sheet">
        <option value="Sheet1">Sheet1</option>
        <option value="Sheet2">Sheet2</option>
      </select> Sheet<br />
      <input id="sub" type="submit" value="Submit" />
    </form>
    <div id="output"></div>
  </body>
</html>

aq1.gs:

function processForm(formObject) {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName(formObject.sheet);
  sh.appendRow([formObject.first,formObject.last]);
  return Utilities.formatString('First: %s<br />Last: %s<br />Sheet: %s', formObject.first,formObject.last,formObject.sheet);
}

function runOne() {//This loads the dialog
  var userInterface=HtmlService.createHtmlOutputFromFile('aq4').setWidth(1000);
  SpreadsheetApp.getUi().showModelessDialog(userInterface, "My Form Example")
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Cooper
  • 59,616
  • 6
  • 23
  • 54