17

我继承了一个 Web 应用程序,其中在任何输入字段中按回车键的通常功能已被禁用,原因是页面包含多个表单,并且应用程序无法确定(或者,我被告知) 采取行动的形式。应用程序的设计没有提交按钮(如 input type="submit"),相反,设计人员已经进行了 onclick 处理。这是在其中一个页面上定义的两个按钮,包括用于说明

<input type="button" value="LOGIN"  name="btnLoginOk" onclick="submit(); />"

<input type="button" class="button-click-grey" value="Find Link Partners"  
    onclick="raiseEvent('SubmitForm','',this);" style="cursor:pointer;" />

但我真的希望能够允许用户在他们愿意的情况下按回车键,例如,如果他们刚刚输入了与 LOGIN 关联的字段,然后检测到并执行 onclick="submit();"

也许 jQuery 有一个解决方案。

4

4 回答 4

37

页面包含多个表单,应用程序将无法确定(或者,我被告知)要执行哪个表单。

当您在输入控件上按 enter 时,浏览器会在该表单中查找第一个提交按钮并模拟单击它。在多个按钮的情况下,第一个将在键盘输入时按下(这绝不是一成不变的,浏览器可能会偏离这一点)。

如果您有两个表单,则获得按键的表单将按下一个提交按钮。因此,您实际上并不需要对此进行任何特殊处理。你只需要停止挡路。

您可以在代码中以表格形式模拟这一点:

 $( 'form' ).bind('keypress', function(e){
   if ( e.keyCode == 13 ) {
     $( this ).find( 'input[type=submit]:first' ).click();
   }
 });

或窗口(用于演示大致发生的情况):

 $( window ).bind('keypress', function(e){
   if ( $( e.originalTarget ).is( ':input' ) && e.keyCode == 13 ) {
     $(  e.originalTarget )
       .closest( 'form' )
         .find( 'input[type=submit]:first' )
           .click();
   }
 });

当然,假设.preventDefault()该事件尚未被调用。

底线:如果您有事件,您可以从中推断出它来自什么元素,因此它属于哪种形式。即使在这种情况下:

<input type="button" value="LOGIN" name="btnLoginOk" onclick="submit();">

submit()是一个全局函数,但是当它被调用时,它的 context ( this) 将是元素,你可以这样做submit(e){ this.form.submit(); }

应用程序的设计没有提交按钮(如 input type="submit"),相反,设计人员已经进行了 onclick 处理。

在我看来,这听起来像是设计师没有完全理解 DOM / 表单事件,并且正在解决这个问题。另一个可能的原因可能是程序很旧,并且是在这些东西不像今天那样稳定或没有正确记录的时候重新设计的。

替换这个:

<form action="/login/" method="POST">
  [...]
  <input type="button" value="LOGIN" name="btnLoginOk" onclick="submit();">
</form>

有了这个:

<form action="/login/" method="POST">
  [...]
  <input type="submit" value="LOGIN" name="btnLoginOk">
</form>

然后向所有需要它的表单添加一个键处理程序,如果满足某些条件,它会检测并禁止输入(对于您实际上确实想要禁用它的表单)。

// for all forms that POST that have 2+ submit buttons
$( 'form[method=post]:has(:submit:eq(1))' ).bind('keydown', function(e){
  // if target is an enter key, input element, and not a button
  if ( e.keyCode == 13 && e.target.tagName == 'INPUT' && 
       !/^(button|reset|submit)$/i.test( e.target.type ) ) {
    return false;  // kill event
  }
});

或者更好的是:使用知道如何为您执行此操作的表单验证库(或 jQuery 插件)。

于 2009-04-19T02:52:52.040 回答
4

您可以在 jquery 中为 Enter 键绑定按键事件:

$("form").bind("keypress", function(e) {
   if (e.keyCode == 13) {
      your_custom_submit_function();
      return false; // ignore the default event
   }
});
于 2011-07-26T15:41:09.467 回答
3

手指交叉这会工作

$(document).ready(function() {
  var focussed_form;
  $('input').focus(focus_form);
  $('input').blur(unfocus_form);
  $('textarea').focus(focus_form);
  $('textarea').blur(unfocus_form);
  $('select').focus(focus_form);
  $('select').blur(unfocus_form);

  $(document).keypress(function(e) {
    if(e.keyCode == 13) 
    {
      $(focussed_form).trigger('submit'); 
    }
  });

  function focus_form(){
    focussed_form = $(this).closest('form');
  }

  function unfocus_form(){
    focussed_form = NULL;
  }

});
于 2009-04-18T23:33:45.827 回答
2

我认为您不需要 jQuery 或 javascript。您确实可以检测到用户在哪个表单上点击了提交,甚至可以检测到哪个提交按钮被点击(如果每个表单有多个提交按钮)。

这是您将使用的代码:

<form action="http://foo.com/uri" method="POST">
  <input type="submit" name="action1a" value="add" />
  <input type="submit" name="action1b" value="delete" />
</form>
<form action="http://foo.com/uri" method="POST">
  <input type="submit" name="action2a" value="add" />
  <input type="submit" name="action2b" value="delete" />
  <input type="submit" name="action2c" value="someOtherAction" />
</form>

然后对于表单处理脚本,您只需检查提交按钮的名称,例如:

if (isset($_POST['action1a'])) ... // PHP syntax

或者,您可以使用图像作为提交按钮,然后您可以为所有提交按钮使用相同的名称并检查它们的值——如果每个按钮都有唯一的value属性,您也可以使用普通提交按钮执行此操作。


编辑:另一种方法是结合 POST 和 GET 值,即:

<form action="http://foo.com/uri?form=1" method="POST">
  <input type="submit" name="action" value="add" />
  <input type="submit" name="action" value="delete" />
</form>
<form action="http://foo.com/uri?form=2" method="POST">
  <input type="submit" name="action" value="add" />
  <input type="submit" name="action" value="delete" />
</form>
于 2009-04-18T23:40:42.223 回答