HTML keydown Event Listener

This question is more of HTML.
I want to use CMD + Enter to submit the form.
I have a input and a textarea label.
I added event listener: *.addEventListener('keypress', keypressHandler(e), false);

Problem: no matter what I put in the * above (window, body, table, textarea, etc. In fact, I can put literally whatever, or just delete the *., leaving addEventListener('keypress', keypressHandler(e), false);), the function seems only to work when the one-line input area (Subject) is active. But it is more useful to work when the Text Area area (or both the Subject and the Text Area) is active.

Edit: the function does not work at all. I deleted the eventListener code, "CMD + Enter" still works when the Subject area is active. I guess the behavior is innately related to input element. It does not apply to textarea.

(my workflow is to type something in the Subject area, then in the Text Area area, then hit CMD + Enter to Submit.)

My code:

<html>
 <head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
    <meta content="en-us" http-equiv="Content-Language" />
    <title>Keyboard Maestro Custom HTML Prompt</title>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <style type="text/css">
  body {font-family: Ezra SIL, Times New Roman, sans-serif; margin: 5px; background-color: #DEB887;}
  table, th, td { border: 1px solid #000000; background-color: #DEB887; padding: 5px; vertical-align: middle;}
  .caption {font-weight: bold;}
  .subjectField, .textAreaField {width: 100%;}
  .subjectField, .textAreaField {height: 100%;}
  .instructionField {margin-left:10px; font-family: Times New Roman; font-size: small;}
  .buttonDiv {margin-top: 20px; margin-right: 20px; text-align: left;}
  .btnDefault, .btnCancel, .btnOther {border-radius: 28px; font-family: Arial; color: black; font-size: 14px; 
                         text-decoration: none; font-weight: bold; margin-left: 5px; padding:  5px 20px 5px 20px;}
  .btnDefault {background: blue; color: white; border: solid lightblue 2px;}
  .btnCancel {background: white; color: black; border: solid blue 2px;}
  .btnOther {background: #e6e6e6; color: black; border: solid black 2px;}
  .btnDefault:hover,.btnCancel:hover, .btnOther:hover {background: #fcfc3c; text-decoration: none; color: black;}
  .btnRadio, .btnCheckbox {margin-left: 5px; font-weight: normal;}
  </style>
 
<script>
	function KMInit() {
		window.addEventListener("resize", savePosition, true);
		window.addEventListener("unload", savePosition, true); 
		textarea.addEventListener('keydown', keydownHandler(e), false);
	} 

	function keydownHandler(e) {
		if(e.keyCode == 13 && e.metaKey) {
		submitWindow(event);
		}
	}

	function KMWindow() {
		winBounds = window.KeyboardMaestro.GetVariable("savedTestWindowPosition");
		if(!winBounds) {
			winBounds = window.KeyboardMaestro.GetVariable("TestDefaultWindowSize");
			}
		return winBounds;
		} 

	function savePosition() {
		window.KeyboardMaestro.SetVariable('savedTestWindowPosition', [window.screenX, window.screenY + 16, window.innerWidth,window.innerHeight].join(',') );
		}

	function submitWindow(event) {
		savePosition();
		window.KeyboardMaestro.Submit( event );
		}

	function cancelWindow(event) {
		savePosition();
		window.KeyboardMaestro.Cancel( event );
		}

</script>
 
 </head>

 <body>

  <div style="text-align: center;">Post Announcement</div>
  <form action="#" method="post">

  <table style="width: 99%; height: 85%;" cellspacing="0" cellpadding="10">
  <tbody> 

    <tr> <td width="100px"; height="15px"> <div class="caption">Subject:</div> </td>
    <td> <input class="subjectField" name="instanceSubject" id="subject" autofocus="" type="text" /></td> </tr>

    <tr> <td> <div class="caption">Text Area</div> </td>
    <td><textarea class="textAreaField" name="instanceMessage" id="message"></textarea></td> </tr> 

    <tr><td height="10px" colspan="2">
	<div class="instructionField">Note: Just write as you normally would.<br>
	</div> </td></tr>
  </tbody> </table>

      			<!-- ========== BUTTONS ========= -->
    <div class="buttonDiv">
    <button class="btnDefault" name="Save" type="submit" title="Press RETURN to submit"
      onclick="submitWindow('Submit');">Submit</button>
    <button class="btnCancel" name="Cancel" type="button" title="Press ESC to cancel"
      onclick="cancelWindow('Cancel');">Cancel</button> </div> </form>

 </body>
</html>

David Walsh had a piece on that you might find helpful:
Command + Enter to Submit Forms

Thanks, @mrpasini.
I came across his post before and have tried to use the code. But I could not make it work.

Yeah, there are some shortcomings in Keyboard Maestro's WebKit implementation regarding JavaScript. Try a simple alert(), for example. Not implemented.

I dumped some JavaScript code into Napkin to enable tabs in a textarea. That might provide a clue.

Have either of you tried Walsh's technique outside of KM, like just in a HTML file opened in Chrome or Safari?

I'm self-taught on coding. Most of the time, I just take whatever I can find online and make changes to suit my needs. Therefore, when things go wrong, I might not even know what is the problem.
I have tried to test it as a normal HTML file, but it does not seem to work either.

I have simplified the code to alert me when the function is called onload, and when the Enter key is down. But it's not working in either Safari or Chrome. I would love to learn where I did wrong. Here is the simplified code for Safari or Chrome:

<html>
 <head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
    <meta content="en-us" http-equiv="Content-Language" />
    <title>Keyboard Maestro Custom HTML Prompt</title>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <style type="text/css">
  body {font-family: Ezra SIL, Times New Roman, sans-serif; margin: 5px; background-color: #DEB887;}
  table, th, td { border: 1px solid #000000; background-color: #DEB887; padding: 5px; vertical-align: middle;}
  .caption {font-weight: bold;}
  .subjectField, .textAreaField {width: 100%;height: 100%;}
  .instructionField {margin-left:10px; font-family: Times New Roman; font-size: small;}
  .buttonDiv {margin-top: 20px; margin-right: 20px; text-align: left;}
  .btnDefault, .btnCancel {border-radius: 28px; font-family: Arial; color: black; font-size: 14px;
                         text-decoration: none; font-weight: bold; margin-left: 5px; padding:  5px 20px 5px 20px;}
  .btnDefault {background: blue; color: white; border: solid lightblue 2px;}
  .btnCancel {background: white; color: black; border: solid blue 2px;}
  .btnDefault:hover,.btnCancel:hover, .btnOther:hover {background: #fcfc3c; text-decoration: none; color: black;}
  </style>

<script>

	function calledOnload() {
		textarea.addEventListener('keydown', keydownHandler(e), false);
    alert("addEventListener active");
	}

	function keydownHandler(e) {

    if(e.keyCode == 13) {
		alert("Enter key down");
		}

		if(e.keyCode == 13 && e.metaKey) {
		alert("Enter and CMD are pressed");
		}
	}
</script>

 </head>

 <body onload="calledOnload()">
  <div style="text-align: center;">Post Announcement</div>
  <form action="#" method="post">

  <table style="width: 99%; height: 85%;" cellspacing="0" cellpadding="10">
  <tbody>

    <tr> <td width="100px"; height="15px"> <div class="caption">Subject:</div> </td>
    <td> <input class="subjectField" name="instanceSubject" id="subject" autofocus="" type="text" /></td> </tr>

    <tr> <td> <div class="caption">Text Area</div> </td>
    <td><textarea class="textAreaField" name="instanceMessage" id="message"></textarea></td> </tr>

    <tr><td height="10px" colspan="2">
	<div class="instructionField">Note: Just write as you normally would.<br>
	</div> </td></tr>
  </tbody> </table>

      			<!-- ========== BUTTONS ========= -->
    <div class="buttonDiv">
    <button class="btnDefault" name="Save" type="submit" title="Press RETURN to submit"
      onclick="submitWindow('Submit');">Submit</button>
    <button class="btnCancel" name="Cancel" type="button" title="Press ESC to cancel"
      onclick="cancelWindow('Cancel');">Cancel</button> </div> </form>

 </body>
</html>

Thanks for the reply. That's a huge clue. It is good to get KM out of the equation.
So first, we need to make it work with a standalone file.
When I get some time, I'll give it a try.

Problem solved. This is a workable code:

<html>
 <head>
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
    <meta content="en-us" http-equiv="Content-Language" />
    <title>Keyboard Maestro Custom HTML Prompt</title>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
    <style type="text/css">
  body {font-family: Ezra SIL, Times New Roman, sans-serif; margin: 5px; background-color: #DEB887;}
  table, th, td { border: 1px solid #000000; background-color: #DEB887; padding: 5px; vertical-align: middle;}
  .caption {font-weight: bold;}
  .subjectField, .textAreaField {width: 100%;height: 100%;}
  .instructionField {margin-left:10px; font-family: Times New Roman; font-size: small;}
  .buttonDiv {margin-top: 20px; margin-right: 20px; text-align: left;}
  .btnDefault, .btnCancel {border-radius: 28px; font-family: Arial; color: black; font-size: 14px; 
                         text-decoration: none; font-weight: bold; margin-left: 5px; padding:  5px 20px 5px 20px;}
  .btnDefault {background: blue; color: white; border: solid lightblue 2px;}
  .btnCancel {background: white; color: black; border: solid blue 2px;}
  .btnDefault:hover,.btnCancel:hover, .btnOther:hover {background: #fcfc3c; text-decoration: none; color: black;}
  </style>
 
<script>
	function KMInit() {
		window.addEventListener("resize", savePosition, true);
		window.addEventListener("unload", savePosition, true); 
		window.addEventListener("keydown", function(e){
		    if(e.keyCode == 13 && e.metaKey) {
       			submitWindow(event);
		    }
		});
	} 

	function KMWindow() {
		winBounds = window.KeyboardMaestro.GetVariable("savedTestWindowPosition");
		if(!winBounds) {
			winBounds = window.KeyboardMaestro.GetVariable("TestDefaultWindowSize");
			}
		return winBounds;
		} 

	function savePosition() {
		window.KeyboardMaestro.SetVariable('savedTestWindowPosition', [window.screenX, window.screenY + 16, window.innerWidth,window.innerHeight].join(',') );
		}

	function submitWindow(event) {
		savePosition();
		window.KeyboardMaestro.Submit( event );
		}

	function cancelWindow(event) {
		savePosition();
		window.KeyboardMaestro.Cancel( event );
		}

</script>
 
 </head>

 <body>

  <div style="text-align: center;">Post Announcement</div>
  <form action="#" method="post">

  <table style="width: 99%; height: 85%;" cellspacing="0" cellpadding="10">
  <tbody> 

    <tr> <td width="100px"; height="15px"> <div class="caption">Subject:</div> </td>
    <td> <input class="subjectField" name="instanceSubject" id="subject" autofocus="" type="text" /></td> </tr>

    <tr> <td> <div class="caption">Text Area</div> </td>
    <td><textarea class="textAreaField" name="instanceMessage" id="message"></textarea></td> </tr> 

    <tr><td height="10px" colspan="2">
	<div class="instructionField">Note: Just write as you normally would.<br>
	</div> </td></tr>
  </tbody> </table>

      			<!-- ========== BUTTONS ========= -->
    <div class="buttonDiv">
    <button class="btnDefault" name="Save" type="submit" title="Press RETURN to submit"
      onclick="submitWindow('Submit');">Submit</button>
    <button class="btnCancel" name="Cancel" type="button" title="Press ESC to cancel"
      onclick="cancelWindow('Cancel');">Cancel</button> </div> </form>

 </body>
</html>

Thanks for sharing. What change made it work?

I did not fully understand. But since you asked. I did some tests. Here are my findings:

There are two workable ways:

  1. The function has to be embedded in the addEventListener. In this case, it has to be the word function:
	function KMInit() {
		window.addEventListener("keydown", function(e){
		    if(e.keyCode == 13 && e.metaKey) {
       			submitWindow(event);
      			}
     		});
	} 

We can NOT change function to a function name, such as keydownHandler. This will NOT work:

	function KMInit() {
		window.addEventListener("keydown", keydownHandler(e){
		    if(e.keyCode == 13 && e.metaKey) {
       			submitWindow(event);
      			}
     		});
  1. We can use a function name in the addEventListener and define it in another place:
	function KMInit() {
     		window.addEventListener("keydown", keydownHandler);
	} 

	function keydownHandler(e) {
		if(e.keyCode == 13 && e.metaKey) {
		submitWindow(event);
		}
	}

In this case, we can NOT put a parenthesis after the function name in the addEventListener, such as: keydownHandler() or keydownHandler(e). This will NOT work:

	function KMInit() {
		window.addEventListener('keydown', keydownHandler());
	} 

	function keydownHandler(e) {
		if(e.keyCode == 13 && e.metaKey) {
		submitWindow(event);
		}
	}
1 Like

BTW, it has to be either window.addEventListener or document.addEventListener.

These will not work:
textarea.addEventListener,
table.addEventListener
form.addEventListener
Neither do they work in a normal HTML file.

1 Like

Thanks. I really appreciate that, and I'm sure many other KM users will also.

1 Like