【问题标题】:Submit jQuery UI dialog on <Enter>在 <Enter> 上提交 jQuery UI 对话框
【发布时间】:2010-10-26 12:22:22
【问题描述】:

我有一个带有表单的 jQuery UI 对话框。我想模拟单击对话框的一个按钮,这样您就不必使用鼠标或标签。换句话说,我希望它像一个普通的 GUI 对话框一样模拟点击“确定”按钮。

我认为这可能是对话框中的一个简单选项,但我在 jQuery UI documentation 中找不到它。我可以用 keyup() 绑定每个表单输入,但不知道是否有更简单/更干净的方法。谢谢。

【问题讨论】:

标签: javascript jquery jquery-ui


【解决方案1】:

我不知道 jQuery UI 小部件 中是否有选项,但您可以简单地将 keypress 事件绑定到包含您的对话框的 div。 ..

$('#DialogTag').keypress(function(e) {
    if (e.keyCode == $.ui.keyCode.ENTER) {
          //Close dialog and/or submit here...
    }
});

无论对话框中的焦点是什么元素,它都会运行,这取决于你想要什么,这可能是一件好事,也可能不是一件好事。

如果你想把它设为默认功能,你可以添加这段代码:

// jqueryui defaults
$.extend($.ui.dialog.prototype.options, { 
    create: function() {
        var $this = $(this);

        // focus first button and bind enter to it
        $this.parent().find('.ui-dialog-buttonpane button:first').focus();
        $this.keypress(function(e) {
            if( e.keyCode == $.ui.keyCode.ENTER ) {
                $this.parent().find('.ui-dialog-buttonpane button:first').click();
                return false;
            }
        });
    } 
});

下面是更详细的视图:

$( "#dialog-form" ).dialog({
  buttons: { … },
  open: function() {
    $("#dialog-form").keypress(function(e) {
      if (e.keyCode == $.ui.keyCode.ENTER) {
        $(this).parent().find("button:eq(0)").trigger("click");
      }
    });
  };
});

【讨论】:

  • 没关系,我找到了:将“打开”添加到对话框(如关闭、模态、bgiframe 等)并将 keyup 处理程序挂在那里。
  • 对于 Webkit (Safari/Chrome),这仅在我执行“keydown”而不是“keyup”时才有效。不确定这是否是最近的更改,或者我的页面上是否还有真实表格是否重要。不过,感谢您的提示!
  • 你可以用 if (e.keyCode === $.ui.keyCode.ENTER) 代替 if (e.keyCode == 13) 来增加可读性。
  • 我否决了这个答案。虽然它简短而整洁,但在 Firefox 7.0.1 中,如果用户从自动完成下拉框中选择某些内容,这也会触发您的“确定”按钮,例如以前输入的电子邮件地址。
  • 在“open:”中绑定事件是个坏主意。这将导致它在每次打开对话框时重新绑定,这意味着如果对话框打开两次,事件处理程序将被调用两次。
【解决方案2】:

我已经总结了上面的答案并添加了重要的东西

$(document).delegate('.ui-dialog', 'keyup', function(e) {
        var target = e.target;
        var tagName = target.tagName.toLowerCase();

        tagName = (tagName === 'input' && target.type === 'button') 
          ? 'button' 
          : tagName;

        isClickableTag = tagName !== 'textarea' && 
          tagName !== 'select' && 
          tagName !== 'button';

        if (e.which === $.ui.keyCode.ENTER && isClickableTag) {
            $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');

            return false;
        }
    });

优点:

  1. 不允许在不兼容的元素上输入键,例如 textareaselectbutton 或带有类型按钮的输入,假设用户在 textarea 上单击输入并提交表单而不是换行!
  2. 绑定一次完成,避免使用对话框'open'回调绑定回车键,避免每次对话框'open'时重复绑定同一个函数
  3. 避免按照上述一些答案的建议更改现有代码
  4. 使用 'delegate' 而不是已弃用的 'live' 并避免使用新的 'on' 方法以允许使用旧版本的 jquery
  5. 因为我们使用了委托,这意味着甚至可以在初始化对话框之前编写上面的代码。即使没有$(document).ready,您也可以将其放入 head 标签中
  6. 此外,为了提高效率,delegate 只会将一个处理程序绑定到document,并且不会像上面的某些代码那样将处理程序绑定到每个对话框。
  7. 甚至可以使用动态生成的对话框,例如$('&lt;div&gt;&lt;input type="text"/&gt;&lt;/div&gt;').dialog({buttons: .});
  8. 与 ie 7/8/9 合作!
  9. 避免使用慢速选择器:first
  10. 避免使用类似答案here 的技巧来制作隐藏的提交按钮

缺点:

  1. 将第一个按钮作为默认按钮运行,您可以使用eq()选择另一个按钮或在if语句中调用函数
  2. 所有对话框都将具有相同的行为,您可以通过使选择器更具体来过滤它,即“#dialog”而不是'.ui-dialog'

我知道这个问题很老,但我也有同样的需求,所以我分享了我使用的解决方案。

【讨论】:

  • 这不是公认的答案并且没有更多选票的事实让我感到难过,最多信息并且不会不断添加处理程序。 +1
  • 很好的答案,你要避免打开回调来添加绑定
  • 对我来说,这在事件为 keydown 时有效,我删除了 tagName 的所有条件并删除了点击触发器
  • 我还必须更改为“keydown”才能完成这项工作(在 OS X 10.8.4、Chrome 29 和 Firefox 23 上测试)。
  • 由于这是一个较旧的答案,值得注意的是 .delegate() 在 jQuery 3.0 中已被弃用,因此 .on()(自 1.7 起可用)可能是此时的路线。
【解决方案3】:
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

它与最新版本的 JQuery UI (1.8.1) 完美配合。 您也可以使用 :first 代替 :last ,具体取决于您要将哪个按钮设置为默认按钮。

与上面选择的解决方案相比,此解决方案的优点是显示哪个按钮是用户的默认按钮。用户还可以在按钮之间按 TAB,按 ENTER 将单击当前处于焦点的按钮。

干杯。

【讨论】:

  • 如果您的对话框有一个或多个文本输入字段怎么办?当用户在用户名和密码字段中时,我希望 ENTER 提交登录对话框。
  • @David 如果您使用的是 jQuery 对话框按钮,那么只需隐藏表单上的正常输入提交按钮。例如。可见性:隐藏;
【解决方案4】:

一种使这项工作更通用的粗略但有效的方法:

$.fn.dlg = function(options) {
    return this.each(function() {
             $(this).dialog(options);
             $(this).keyup(function(e){
                  if (e.keyCode == 13) {                
                       $('.ui-dialog').find('button:first').trigger('click');
                  }
             });
    });
}

然后,当您创建一个新对话框时,您可以这样做:

$('#a-dialog').mydlg({...options...})

然后像普通的 jquery 对话框一样使用它:

$('#a-dialog').dialog('close')

有一些方法可以改进它以使其在更特殊的情况下工作。使用上面的代码,它会自动选择对话框中的第一个按钮作为按下回车键时触发的按钮。它还假设在任何给定时间只有一个活动对话,但情况可能并非如此。但你明白了。

注意:如上所述,输入时按下的按钮取决于您的设置。因此,在某些情况下,您可能希望在 .find 方法中使用 :first 选择器,而在其他情况下,您可能希望使用 :last 选择器。

【讨论】:

  • 我认为那里应该有一个 .first() ,如 $('.ui-dialog').find('button').first().trigger('click');否则,如果有多个按钮,您将触发单击对话框的所有按钮。
  • @thejh - 不,它为每个对话框附加一个 keyup 事件处理程序,但只有在按下键时包含焦点元素的对话框才会接收事件。
【解决方案5】:

您可以在对话框中绑定到表单的提交事件,然后执行以下操作:

$("#my_form").parents('.ui-dialog').first().find('.ui-button').first().click();

所以,整个事情看起来像这样

$("#my_form").dialog({
  open: function(){
    //Clear out any old bindings
    $("#my_form").unbind('submit');
    $("#my_form").submit(function(){
      //simulate click on create button
      $("#my_form").parents('.ui-dialog').first().find('.ui-button').first().click();
      return false;
    });
  },
  buttons: {
    'Create': function() {
      //Do something
    },
    'Cancel': function() {
      $(this).dialog('close');
    }
  }
});

请注意,不同的浏览器处理回车键的方式不同,有些浏览器并不总是在回车时进行提交。

【讨论】:

  • 这似乎是最优雅的答案。
  • 当我在同一个对话框中有三个或更多输入时,这不起作用。不知道为什么。
【解决方案6】:

Ben Clayton 是最简洁和最短的,它可以在初始化任何 jquery 对话框之前放置在索引页面的顶部。但是,我想指出“.live”已被弃用。首选操作现在是“.on”。如果您希望“.on”像“.live”一样运行,则必须使用委托事件来附加事件处理程序。此外,还有一些其他的事情......

  1. 我更喜欢使用 ui.keycode.ENTER 方法来测试回车 键,因为您不必记住实际的键码。

  2. 使用“$('.ui-dialog-buttonpane button:first', $(this))” 点击选择器使整个方法通用。

  3. 您要添加“return false;”防止违约并停止 传播。

在这种情况下...

$('body').on('keypress', '.ui-dialog', function(event) { 
    if (event.keyCode === $.ui.keyCode.ENTER) { 
        $('.ui-dialog-buttonpane button:first', $(this)).click();
        return false;
    }
});

【讨论】:

    【解决方案7】:

    我不知道更简单,但通常您会跟踪哪个按钮具有当前焦点。如果焦点更改为不同的控件,则“按钮焦点”将保留在最后获得焦点的按钮上。通常,“按钮焦点”将从您的默认按钮开始。切换到不同的按钮会改变“按钮焦点”。您必须决定导航到不同的表单元素是否会将“按钮焦点”再次重置为默认按钮。除了浏览器默认值之外,您可能还需要一些视觉指示器来指示焦点按钮,因为它在窗口中失去了真正的焦点。

    一旦您完成并实现了按钮焦点逻辑,那么我可能会向对话框本身添加一个键处理程序,并让它调用与当前“焦点”按钮关联的操作。

    编辑:我假设您希望能够在填写表单元素的任何时候按 Enter 键,并优先考虑“当前”按钮操作。如果您只希望在按钮实际获得焦点时出现这种行为,那么我的回答太复杂了。

    【讨论】:

      【解决方案8】:

      我找到了这个解决方案,它适用于 IE8、Chrome 23.0 和 Firefox 16.0

      它基于罗伯特·施密特的评论。

      $("#id_dialog").dialog({
          buttons: [{
              text: "Accept",
              click: function() {
                  // My function
              },
              id: 'dialog_accept_button'
          }]
      }).keyup(function(e) {
          if (e.keyCode == $.ui.keyCode.ENTER)
              $('#dialog_accept_button').click();
      });
      

      希望对大家有帮助。

      【讨论】:

      • 谢谢!这为我节省了很多时间! :)
      • 简单有效。最好的答案在这里。为什么在地球上没有将按钮设为默认按钮的选项,我不知道。
      【解决方案9】:

      有时我们忘记了浏览器已经支持的基本原理:

      <input type="submit" style="visibility:hidden" />
      

      这将导致 ENTER 键提交表单。

      【讨论】:

        【解决方案10】:

        我是这样做的... ;) 希望它对某人有帮助..

        $(window).keypress(function(e) {
            if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                $(".ui-dialog:visible").find('.ui-dialog-buttonpane').find('button:first').click();
                return false;
            }
        });
        

        【讨论】:

          【解决方案11】:

          这应该可以触发按钮的点击处理程序的点击。此示例假定您已经在对话框中设置了表单以使用 jquery.validate 插件。但可以很容易地适应。

          open: function(e,ui) {
              $(this).keyup(function(e) {
                  if (e.keyCode == 13) {
                     $('.ui-dialog-buttonpane button:last').trigger('click');
                  }
              });
          },
          buttons: {
              "Submit Form" : function() {
                      var isValid = $('#yourFormsID').valid();
                      // if valid do ajax call
                      if(isValid){
                         //do  your ajax call here. with serialize form or something...
          
                      }
          }
          

          【讨论】:

            【解决方案12】:

            我意识到已经有很多答案,但我自然认为我的解决方案是最简洁的,并且可能是最短的。它的优点是它适用于未来任何时间创建的任何对话框。

            $(".ui-dialog").live("keyup", function(e) {
                if (e.keyCode === 13) {
                    $('.ok-button', $(this) ).first().click();
                }
            });
            

            【讨论】:

            • 谢谢你的更新,只是一个小问题,这里的“.ok-button”是什么?它是你必须在你想用回车点击的默认按钮上应用的类吗?
            • 对不起,如果你发现这个问题很愚蠢.. m 在 JS/jQuery 中太新了
            • @BenClayton :如果您将其放在 jQueryUI 对话框的上下文中,则可以改进此答案。
            【解决方案13】:

            这是我所做的:

            myForm.dialog({
              "ok": function(){
                ...blah...
              }
              Cancel: function(){
                ...blah...
              }
            }).keyup(function(e){
              if( e.keyCode == 13 ){
               $(this).parent().find('button:nth-child(1)').trigger("click");
              }
            });
            

            在这种情况下,myForm 是一个包含表单 html 的 jQuery 对象(请注意,那里没有任何“表单”标签...如果您将它们放在整个屏幕中,当您按“输入”时会刷新) .

            每当用户在表单中按“输入”时,就相当于单击“确定”按钮。

            这也避免了在“确定”按钮已经突出显示的情况下打开表单的问题。虽然这对于没有字段的表单很有用,但如果您需要用户填写内容,那么您可能希望突出显示第一个字段。

            【讨论】:

            • 这是最合乎逻辑的解决方案。如果您使用 id 声明按钮并将选择器传递给 find() 则更好,但任何一种方式都有效。 +1
            【解决方案14】:

            做完了

              $('#login input').keyup(function(e) {
                  if (e.keyCode == 13) {
                      $('#login form').submit();
                  }
               }
            

            【讨论】:

              【解决方案15】:

              如果你知道按钮元素选择器:

              $('#dialogBox').dialog('open');
              $('#okButton').focus();
              

              应该为您解决问题。正如您所期望的那样,这将聚焦 ok 按钮,然后 enter 将“单击”它。这与原生 UI 对话框中使用的技术相同。

              【讨论】:

                【解决方案16】:
                   $("#LogOn").dialog({
                       modal: true,
                       autoOpen: false,
                       title: 'Please Log On',
                       width: 370,
                       height: 260,
                       buttons: { "Log On": function () { alert('Hello world'); } },
                       open: function() { $(this).parents('.ui-dialog-buttonpane button:eq(0)').focus();}
                   });
                

                【讨论】:

                  【解决方案17】:

                  我为这个问题找到了一个非常简单的解决方案:

                  var d = $('<div title="My dialog form"><input /></div>').dialog(
                      buttons: [{
                          text: "Ok",
                          click: function(){
                              // do something
                              alert('it works');
                          },
                          className: 'dialog_default_button'
                      }]
                  });
                  
                  $(d).find('input').keypress(function(e){
                      if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
                          e.preventDefault();
                          $('.dialog_default_button').click();
                      }
                  });
                  

                  【讨论】:

                    【解决方案18】:
                    $('#DialogID').dialog("option", "buttons")["TheButton"].apply()
                    

                    这对我很有用..

                    【讨论】:

                    • 最好包含对 $('#DialogID').dialog() 的引用作为应用的参数。否则 $(this).close() 在 TheButton 内将没有正确的上下文。
                    【解决方案19】:

                    这些解决方案在 IE9 中似乎都不适合我。我最终得到了这个..

                    $('#my-dialog').dialog({
                        ...
                        open: function () {
                            $(this).parent()
                                   .find("button:eq(0)")
                                   .focus()
                                   .keyup(function (e) {
                                       if (e.keyCode == $.ui.keyCode.ENTER) {
                                           $(this).trigger("click");
                                       };
                                   });
                        }
                    });
                    

                    【讨论】:

                      【解决方案20】:

                      使用下面的body是因为在body上添加了dialog DIV,所以body现在监听键盘事件。它在 IE8、9、10、Mojila、Chrome 上进行了测试。

                      open: function() {
                      $('body').keypress(function (e) { 
                           if (e.keyCode == 13) {   
                           $(this).parent().find(".ui-dialog-buttonpane button:eq(0)").trigger("click");
                           return false; 
                           }
                        }); 
                      }
                      

                      【讨论】:

                        【解决方案21】:

                        因为我没有足够的声望来发布 cmets。

                        $(document).delegate('.ui-dialog', 'keyup', function(e) {
                          var tagName = e.target.tagName.toLowerCase();
                        
                          tagName = (tagName === 'input' && e.target.type === 'button') ? 'button' : tagName;
                        
                          if (e.which === $.ui.keyCode.ENTER && tagName !== 'textarea' && tagName !== 'select' && tagName !== 'button') {
                              $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');
                            return false;
                          } else if (e.which === $.ui.keyCode.ESCAPE) {
                              $(this).close();
                          }
                        });
                        

                        Basemm #35 修改的答案也添加了 Escape 以关闭对话框。

                        【讨论】:

                          【解决方案22】:

                          很好用,谢谢!!!

                          open: function () { debugger; $("#dialogDiv").keypress(function (e) { if (e.keyCode == 13) { $(this).parent().find("#btnLoginSubmit").trigger("click"); } }); },

                          【讨论】:

                          • hmm ...您的帖子中有什么新内容(与之前的答案相比)吗?
                          【解决方案23】:

                          给你的按钮classes 并按照通常的方式选择它们:

                          $('#DialogTag').dialog({
                            closeOnEscape: true,
                            buttons: [
                              {
                                text: 'Cancel',
                                class: 'myCancelButton',
                                click: function() {
                                  // Close dialog fct
                                }
                              },
                              {
                                text: 'Ok',
                                class: 'myOKButton',
                                click: function() {
                                  // OK fct
                                }
                              }
                            ],
                            open: function() {
                          
                              $(document).keyup(function(event) {
                          
                                if (event.keyCode === 13) {
                                  $('.myOKButton').click();
                                }
                          
                              });
                          
                            }
                          });
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 1970-01-01
                            • 2015-06-15
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-09-08
                            • 2012-05-05
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多