5

I have a table within a form. The table contains some form fields, but there are form fields outside of the table (but still within the form) too.

I know that Enter and Return are traditionally used to submit a form via the keyboard, but I want to stop this behaviour for fields within the table. For example, if I focus a field within the table and hit Enter/Return, nothing happens. If I focus a field outside of the table (but still within the form) then for it to submit as normal.

I have a jQuery plugin that targets this table. Simplified, this is what I've tried this far:

base.on('keydown', function(e) {
    if (e.keyCode == 13) {
        e.stopPropagation();
        return false;
    }
});

Where base is the table jQuery object. This is within my plugin's init method. However, hitting Enter still submits the form.

Where am I going wrong?

EDIT: Some simplified HTML:

<form method="" action="">
  <input type="text" /><!--this should still submit on Enter-->
  <table>
    <tbody>
      <tr>
        <td>
          <input type="text" /><!--this should NOT submit on Enter-->
        </td>
      </tr>
    </tbody>
  </table>
</form>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Martin Bean
  • 38,379
  • 25
  • 128
  • 201
  • 1
    Possible duplicate of http://stackoverflow.com/questions/1563062/prevent-form-submission-with-enter-key and http://stackoverflow.com/questions/895171/prevent-users-from-submitting-form-by-hitting-enter – Mark Walters Apr 25 '12 at 09:41
  • You should mention what is `base`, it looks like a jquery object but it doesn't follow the [naming conventions](http://stackoverflow.com/q/10204606/601179). – gdoron Apr 25 '12 at 09:51
  • @gdoron I did. It's the very first sentence after the first code block! "*Where `base` is the table jQuery object.*" – Martin Bean Apr 25 '12 at 09:54
  • @MartinBean. sorry, but the naming conventions is a thing you really want to follow. sorry for being dumb. – gdoron Apr 25 '12 at 09:55
  • @gdoron As I say, the JavaScript was simplified, but the `base` name comes from this plugin started: http://starter.pixelgraphics.us/ – Martin Bean Apr 25 '12 at 09:56

6 Answers6

9
base.keypress(function(e) {
    var code = e.keyCode || e.which;
    if(code == 13)
        return false;
});

or for only inputs:

$(':input', base).keypress(function(e) {
    var code = e.keyCode || e.which;
    if(code == 13)
        return false;
});
gdoron
  • 147,333
  • 58
  • 291
  • 367
  • 1
    Please re-read the question. I still want the default behaviour to work on form controls outside of my table. – Martin Bean Apr 25 '12 at 09:45
  • So you need to check if any of the elements (inputs) in the table are in focus when the enter key is pressed – Mark Walters Apr 25 '12 at 09:46
  • @gdoron Can I not do this from my plugin up, rather than the form down? For example, I don't want it to apply to inputs of *any* form with a table. – Martin Bean Apr 25 '12 at 09:48
  • @gdoron I want to stop inputs submitting inside tables my plugin is applied to, not just any table inside a form that has an input. – Martin Bean Apr 25 '12 at 09:55
  • @MartinBean. than my updated answer should take care of it, doesn't it? – gdoron Apr 25 '12 at 09:57
  • 1
    Perfect. Got there in the end. I changed my `keyup` event name to `keypress` and I now have the functionality I desired. Thanks! – Martin Bean Apr 25 '12 at 09:58
3

I'm going to guess that a form element will fire the submit event, it doesn't bubble up through the table and on to the form, try this instread:

$('input, select, textarea', base).on('keydown', function(e) {
    if (e.keyCode == 13) {
        return false;
    }
});

Note we're also providing context to the selector, so this keyDown will only occur on elements (modify as required) within your table.

As gordan said in another comment, return false does both .preventDefault() and .stopPropagation()

Ben Everard
  • 13,652
  • 14
  • 67
  • 96
  • You need to limit the selector to only inputs inside the form\table. and actually it's gdoron not gordan... :) – gdoron Apr 25 '12 at 09:48
  • That's what the second parameter, `base`, in the selector is doing, where `base` is my table as a jQuery object. – Martin Bean Apr 25 '12 at 09:49
  • Whoops, my bad on name mistake :P, but it is limiting to the table, as `base` is the table object. – Ben Everard Apr 25 '12 at 09:50
2

e.preventDefault() rather than e.stopPropagation(). stopPropagation only stops it bubbling up to higher DOM nodes, it doesn't prevent the default action.

gdoron
  • 147,333
  • 58
  • 291
  • 367
  • `return false` does them both... – gdoron Apr 25 '12 at 09:42
  • So if I have `return false` in my code, why is the form still submitting? – Martin Bean Apr 25 '12 at 09:43
  • It's not personaly against you, but though this answer was upvoted, it's wrong. `return false` == `e.preventDefault(); e.stopPropagation(); ` – gdoron Apr 25 '12 at 09:50
  • I think you need to re-consider your answer too, gdoron. Yours targets any table within any form, whereas I *only* want to target inputs within a table my plugin is applied to. – Martin Bean Apr 25 '12 at 09:52
1

I found this Q/A trying to sort out a similar situation where I have multiple forms and enter would not do what I wanted. In my specific case, I would dynamically add a new <div id="D1"> D1, D2, D3, etc, and each new div has a form that would reload that div from the same php code that created it, only also with a POST.

Unrelated first problem was I couldn't dynamically create a new function with each div, so I passed the D1, etc, descriptor as an argument to the Javascript function:

<script type="text/javascript">
function formSubmit ( divid ) {
    // post data
    event.preventDefault();
    $.post( "make-my-form-div.php", 
            $("#form"+divid).serialize(), 
            function(data){
                $("#"+divid).html(data);
            });
    return false;
}
</script>

You will see the requisite event.preventDefault(); and return false; that works for the answers in this thread. It didn't work for me. If I click the Submit in any one form, that one div would reload with the correct data. Hitting enter would cause default action and reload the entire page, leaving me with only 1 div.

This Answer worked: I needed a unique ID and NAME for the different forms. Initially, they were <INPUT TYPE="button" VALUE="Submit" onClick="formSubmit('<?php echo $divid ?>');"> but once I added unique ID and NAMES, such as "formD1", etc, it all started working correctly.

Community
  • 1
  • 1
Krista K
  • 21,503
  • 3
  • 31
  • 43
0

This works for me.

$("input[type='text']").on('keypress', function(e) { return e.keyCode != 13; });
Riyaz Hameed
  • 1,087
  • 12
  • 10
0

Just put below code in your template file or in header of page.

<script type="text/javascript">

function stopRKey(evt) {
  var evt = (evt) ? evt : ((event) ? event : null);
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  if ((evt.keyCode == 13) && (node.type=="text"))  {return false;}
}

document.onkeypress = stopRKey;

</script> 
Gokul Shinde
  • 957
  • 3
  • 10
  • 30