在<Enter>上提交jQuery UI对话框


131

我有一个带有表单的jQuery UI对话框。我想模拟对对话框按钮之一的单击,因此您不必在其上使用鼠标或标签。换句话说,我希望它像常规的GUI对话框一样模拟单击“确定”按钮。

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


如果您希望避免使用表单并想要可重用的代码,请在此处提供一个很好的答案:stackoverflow.com/a/9628800/329367
Darren 2012年

Answers:


153

我不知道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");
      }
    });
  };
});

2
没关系,我发现了:在对话框中添加“打开”(如关闭,模态,bgiframe等),然后将keyup处理程序钩在那里。
米兰巴布斯科夫2009年

5
对于Webkit(Safari / Chrome),这仅在我执行“ keydown”而不是“ keyup”时才有效。不知道这是最近的更改还是不重要,我的页面上也有真实的形式。不过,谢谢你的提示!
Nicholas Piasecki

12
可以使用if(e.keyCode === $ .ui.keyCode.ENTER)代替if(e.keyCode == 13)以提高可读性。
A. Murray

2
我不赞成这个答案。它虽然简洁明了,但在Firefox 7.0.1中,如果用户从“自动完成”下拉框中选择某些内容(例如先前输入的电子邮件地址),这也会触发“确定”按钮。
cburgmer'3

2
绑定到“ open:”中的事件是一个坏主意。这将导致它在每次打开对话框时重新绑定,这意味着如果对话框打开两次,则事件处理程序将被调用两次。
Elezar

67

我总结了以上答案并添加了重要内容

$(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”回调来绑定回车键,以避免每次“打开”对话框时都一次又一次地绑定相同的函数。
  3. 如上面的一些答案所示,避免更改现有代码
  4. 使用'delegate'代替不推荐使用的'live'并避免使用新的'on'方法来允许使用旧版本的jquery
  5. 因为我们使用委托,所以即使在初始化对话框之前,也可以编写上面的代码。您甚至也可以将其放在head标签中$(document).ready
  6. 另外,委托将只绑定一个处理程序,document而不会像上面的某些代码那样将处理程序绑定到每个对话框,以提高效率
  7. 即使使用动态生成的对话框(例如 $('<div><input type="text"/></div>').dialog({buttons: .});
  8. 与7/8/9一起工作!
  9. 避免使用慢速选择器 :first
  10. 避免在此处的答案中使用黑客来隐藏提交按钮

缺点:

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

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


4
这不是公认的答案,并且没有更多的选票,这让我很伤心,最能提供信息,并且不能连续添加处理程序。+1
克里斯·奥凯利

1
一个很好的答案,您要避免使用开放的回调来添加绑定
Jay Rizzi 2013年

1
对我来说,这在事件为keydown时有效,我删除了tagName的所有条件并删除了点击触发器
Isaiyavan Babu Karan 2013年

1
我还必须更改为“ keydown”才能使其正常运行(在OS X 10.8.4,Chrome 29和Firefox 23上进行了测试)。
natebeaty 2013年

1
由于这是一个较旧的答案,因此值得注意的.delegate()是jQuery 3.0已弃用,因此.on()(从1.7开始可用)可能是此时的解决方法。
jinglesthula

13
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

它与最新版本的JQuery UI(1.8.1)完美结合。您还可以使用:first而不是:last,这取决于您要将哪个按钮设置为默认按钮。

与上面选择的解决方案相比,该解决方案的优势在于可以显示哪个按钮是用户的默认按钮。用户还可以在按钮之间进行制表,然后按ENTER键将单击当前处于焦点下的按钮。

干杯。


如果您的对话框有一个或多个文本输入字段,该怎么办?当用户位于用户名和密码字段中时,我希望ENTER提交登录对话框。
David Harkness

1
@David,如果您使用的是jQuery对话框按钮,则只需隐藏表单上的普通输入提交按钮即可。例如。可见性:隐藏;
Damo

6

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

$.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')

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

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


我认为应该像$('。ui-dialog')。find('button')。first()。trigger('click');中那样有一个.first();否则,如果有多个按钮,则将触发单击对话框中所有按钮。
贾斯汀·斯托(JustinStolle)2010年

@thejh-不,它会将keyup事件处理程序附加到每个对话框,但是只有按下该键时包含焦点所在元素的对话框才能接收该事件。
David Harkness

6

您可以在对话框中绑定到表单的Submit事件,然后执行以下操作,而不是侦听此答案中的关键代码(我无法开始工作):

$("#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');
    }
  }
});

请注意,不同的浏览器对Enter键的处理方式不同,有些浏览器并不总是在输入时执行提交。


这似乎是最优雅的答案。

当我在同一对话框上有三个或更多输入时,此方法不起作用。不知道为什么。
programad

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;
    }
});

4

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

一旦确定并实现了按钮焦点逻辑,就可能向对话框本身添加一个键处理程序,并让它调用与当前“聚焦”按钮相关联的动作。

编辑:我假设您要随时填写表格元素并以“当前”按钮操作为准。如果您只希望在按钮真正被聚焦时才有这种行为,那么我的答案太复杂了。


3

我找到了这个解决方案,它可以在IE8,Chrome 23.0和Firefox 16.0上运行

它基于Robert Schmidt的评论。

$("#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();
});

我希望它能帮助任何人。


谢谢!那节省了我很多时间!:)
Rahul Desai 2015年

3

有时,我们忘记了浏览器已支持的基本功能:

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

这将导致ENTER密钥提交表单。


2

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

$(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;
    }
});

2

这应该可以触发按钮的单击处理程序的单击。本示例假定您已经在对话框中设置了表单以使用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...

            }
}

1

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

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

1
嘿,谢谢您进行更新,只是一个小问题,这里的“ .ok-button”是什么?您必须在要使用Enter单击的默认按钮上应用的类吗?
2014年

抱歉,如果您发现问题傻了.. m在JS / jQuery中太新了
2014年

@BenClayton:如果将其放在jQueryUI对话框的上下文中,则可以改善此答案。
迈克尔·波特

1

这是我所做的:

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
文森特

1

做完了

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

0

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

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

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


0
   $("#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();}
   });

0

我找到了解决这个问题的简单方法:

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();
    }
});

0
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

这对我来说很棒。


您最好包含对$('#DialogID')。dialog()的引用作为要应用的参数。否则$(this).close()在TheButton中将没有正确的上下文。
戴夫

0

在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");
                   };
               });
    }
});

0

由于在主体上添加了对话框DIV,因此使用了主体下,因此主体现在监听键盘事件。它在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; 
     }
  }); 
}

0

因为我没有足够的声誉来发表评论。

$(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中以关闭对话框。



-1

给您的按钮类,并选择它们通常的方式:

$('#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();
      }

    });

  }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.