在 <Enter> 上提交 jQuery UI 对话框
Posted
技术标签:
【中文标题】在 <Enter> 上提交 jQuery UI 对话框【英文标题】:Submit jQuery UI dialog on <Enter> 【发布时间】:2010-10-26 12:22:22 【问题描述】:我有一个带有表单的 jQuery UI 对话框。我想模拟单击对话框的一个按钮,这样您就不必使用鼠标或标签。换句话说,我希望它像一个普通的 GUI 对话框一样模拟点击“确定”按钮。
我认为这可能是对话框中的一个简单选项,但我在 jQuery UI documentation 中找不到它。我可以用 keyup() 绑定每个表单输入,但不知道是否有更简单/更干净的方法。谢谢。
【问题讨论】:
如果您希望避免使用表单并想要可重用的代码,我在这里提供了一个很好的答案:***.com/a/9628800/329367 【参考方案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;
);
优点:
-
不允许在不兼容的元素上输入键,例如
textarea
、select
、button
或带有类型按钮的输入,假设用户在 textarea
上单击输入并提交表单而不是换行!
绑定一次完成,避免使用对话框'open'回调绑定回车键,避免每次对话框'open'时重复绑定同一个函数
避免按照上述一些答案的建议更改现有代码
使用 'delegate' 而不是已弃用的 'live' 并避免使用新的 'on' 方法以允许使用旧版本的 jquery
因为我们使用了委托,这意味着甚至可以在初始化对话框之前编写上面的代码。即使没有$(document).ready
,您也可以将其放入 head 标签中
此外,为了提高效率,delegate 只会将一个处理程序绑定到document
,并且不会像上面的某些代码那样将处理程序绑定到每个对话框。
甚至可以使用动态生成的对话框,例如$('<div><input type="text"/></div>').dialog(buttons: .);
与 ie 7/8/9 合作!
避免使用慢速选择器:first
避免使用类似答案here 的技巧来制作隐藏的提交按钮
缺点:
-
将第一个按钮作为默认按钮运行,您可以使用
eq()
选择另一个按钮或在if语句中调用函数
所有对话框都将具有相同的行为,您可以通过使选择器更具体来过滤它,即“#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”一样运行,则必须使用委托事件来附加事件处理程序。此外,还有一些其他的事情......
我更喜欢使用 ui.keycode.ENTER 方法来测试回车 键,因为您不必记住实际的键码。
使用“$('.ui-dialog-buttonpane button:first', $(this))” 点击选择器使整个方法通用。
您要添加“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();
);
);
【讨论】:
以上是关于在 <Enter> 上提交 jQuery UI 对话框的主要内容,如果未能解决你的问题,请参考以下文章
通过在 struts-dojo 自动完成上按 enter 键来防止表单提交