当用户按下编辑表单上的删除按钮时,我试图弹出一个确认模式。模态弹出很好,但是当 jQuery 应该提交表单时,它什么也没做。我将删除作为类型 =“按钮”,因为当它是提交类型时,模态函数不会阻止该过程,它只会立即删除用户。
HTML ...
-- 编辑 --
(我添加了 <form>
标签)
<form action="/admin/edit-user" enctype="application/x-www-form-urlencoded" method="post" name="edit_user_form" id="edit_user_form">
...
<p><input type="submit" value="Save" name="submit" id="submit"/></p>
<p><input type="submit" value="Cancel" name="cancel" id="cancel"/></p>
<p><input type="button" value="Delete User" name="delete_btn" id="delete_btn" onclick="confirmDeleteUser();"/></p>
...
</form>
...
<div id="dialog-modal" title="Confirm Delete User">
<p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 0 0;"></span> Are you sure you wish to delete this user?</p>
<p>To continue editing, click cancel.</p>
</div>
Javascript:
function confirmDeleteUser()
{
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
var self = $(this);
var form = $('#edit_user_form');
tmpElm = $('<input type="hidden" />');
tmpElm.attr('name', 'delete');
tmpElm.attr('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
}
});
$('#dialog-modal').dialog('open');
}
当我检查源代码时,我看到代码正确地附加了新的隐藏元素,但提交似乎不想触发。我错过了什么步骤?
最佳答案
尝试不同的方式。
HTML
您的 html 具有以下内容:onclick="confirmDeleteUser();"
为什么? jQuery 应该让您更轻松,不难 .
你的 HTML 应该是纯的并且不调用函数(除了你不太可能遇到的极端情况)。为什么不使用 jQuery 库将事件绑定(bind)到元素,而不是将 javascript 函数调用混合到您的 HTML 中?你应该在 <script>
中做这样的事情标签,在文档就绪语句之后。
$("#delete_btn").click(function(e){
/*Code that runs on click of the "delete_btn" ID tag*/
});
如果您不熟悉 jQuery 选择器和事件,那么 start reading here .您应该这样做的另一个原因是在文档未正确/完全加载的情况下,以防止它破坏您的用户。
CSS
你也这样做了:
style="float:left; margin:0 7px 0 0;"
在 HTML 标签中?这是邪恶的,伙计。只是邪恶。我将如何在五个月内维护此代码?相反,使用 CSS。
在您的标签或 CSS 文件中,您需要一个条目,例如:
.dialogAdjust {
float: left;
margin: 0 7px 0 0;
}
然后在你的 HTML 中你会说:<span class="ui-icon ui-icon-alert dialogAdjust"></span>
现在,您可以根据自己的喜好调整内容。 如果您可以在对话框 div 上创建类,而不是单个 HTML 元素,则更好,在这种情况下,您绝对可以。 JavaScript
好吧,这是你的功能:
function confirmDeleteUser()
{
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
var self = $(this);
var form = $('#edit_user_form');
tmpElm = $('<input type="hidden" />');
tmpElm.prop('name', 'delete');
tmpElm.prop('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
}
});
$('#dialog-modal').dialog('open');
}
这里发生了什么?第一步,您应该尝试使用工具来衡量代码质量。两个流行的是JSHint和 JSLint .您不需要按照他们所说的那样去做,就像这是编写代码的唯一方法一样,但它对于发现由于小错误引起的错误非常有帮助。我喜欢 JSHint,所以我们将通过它来运行它。这是输出:
Errors:
Line 17 tmpElm = $('<input type="hidden" />');
'tmpElm' is not defined.
Line 18 tmpElm.attr('name', 'delete');
'tmpElm' is not defined.
Line 19 tmpElm.attr('id', 'delete');
'tmpElm' is not defined.
Line 20 tmpElm.val(true);
'tmpElm' is not defined.
Line 21 tmpElm.appendTo(form);
'tmpElm' is not defined.
哎呀。看起来你在那里有一个 undefined variable ,这意味着它现在是全局的。全局变量很糟糕,它们会破坏作用域并使您的代码以奇怪的方式运行。我们需要解决这个问题。您应该始终在局部范围内声明局部变量。这意味着输入
var tempElm;
在“删除用户”功能的顶部。去掉那个函数包装器,你就不需要它了。您的代码应该在文档加载完成后创建对话框对象和代码,并在单击时打开对话框。每次单击该按钮时,您的原始代码中都发生了什么,包括创建对话框和打开对话框。这有什么问题?您继续创建对象,即使它已创建。您一次又一次地创建相同的对象。在这个实现中,您不会注意到它,但是除非您现在注意到这一点,否则您的设计将延续到它会用到的地方。
那么,这看起来像什么?在您的
<head>
标签你应该看到这样的东西:<script>
/*
This makes all the code inside
run when the window is done loading,
not before, which may cause issues.
*/
$(window).load(function(){
/*
This sets up the dialog
as you've described before
*/
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
var self = $(this);
var form = $('#edit_user_form');
//We've added the var infront of tepElem
var tmpElm = $('<input type="hidden" />');
tmpElm.prop('name', 'delete');
tmpElm.prop('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
}
});
/*
This is the part where I talked
about selectors and events in the HTML
*/
$("#delete_btn").click(function(e){
$('#dialog-modal').dialog('open');
});
});
</script>
在寻求帮助时,请使用 jsFiddle 之类的工具发布 JavaScript,以便其他人更轻松地帮助您。Here's a jsFiddle of the revisions we've made so far.如果您使用 JavaScript 进行大量工作并希望快速测试某些内容,请花一些时间学习如何使用它。
这就是我想让你学习 jsFiddle 的原因:
你没有给我们足够的代码来成功地工作,因此导致我写了这篇关于代码质量和如何提问的巨额文章,当你发布赏金时更是如此。
如果你需要帮助,不要让人们为之努力工作。除非有人完全疯了,否则你不会得到很好的帮助。
jsFiddle 要求您发布实际的工作代码(或非工作代码),让我们看看 form.submit() 是否存在问题,例如表单元素上的任何奇怪的属性或属性,或任何数量的其他可能存在的问题踢你排除在外。
那么让我们看看是什么破坏了您的“删除用户”功能。
function() {
var self = $(this);
var form = $('#edit_user_form');
tmpElm = $('<input type="hidden" />');
tmpElm.prop('name', 'delete');
tmpElm.prop('id', 'delete');
tmpElm.val(true);
tmpElm.appendTo(form);
form.submit();
return true;
}
form
是 DOM 中使用的保留词,您应该避免使用该词,以免混淆您的变量和 DOM API。 表单的外观:
The w3 explains what forms are and the purpose of things.
关键点:
你的表格里发生了一些奇怪的事情。
这是一个javascript理解如何提交的表单:
http://jsfiddle.net/YS8uW/2/
这是尝试提交表单的 javascript(精简为基本结构):
http://jsfiddle.net/LfDXh/
这里有什么不同?
给定一个提交给某物的 ID,让我们看看你已经完成的一些事情:
http://jsfiddle.net/fdLfC/
当我们不使用它作为 ID 时会发生什么?
http://jsfiddle.net/fdLfC/1/
啊。所以这很奇怪。
这就像给它一个提交的 id 不会让你调用提交。一个正确的解释是,您已经重新编写了它,因为当您分配该 ID 和名称时,dom 会这样做,它试图调用该元素。
如果您打开调试器或其他东西,您可以看到这一点,它会给您以下效果的警报:
TypeError: Property 'submit' of object # is not a function
避免使用关键字来表示其他含义,您就不会落入这些奇怪的陷阱。
非常感谢 @MattMcDonald将我链接到 this resource ,它解释了如何处理 NAME 和 ID 属性覆盖内置 HTML DOM 方法以及为什么。
做我说的其他事情。 免责声明:每个人都会对我发动 war ,说你应该做所有这些事情并不是绝对的,我同意,但我认为这篇文章已经足够长了,我们都同意做这些事情是代码向前迈出的一步质量,而不是倒退。 最后取决于你,但尽量避免把东西混在一起变成一个大而凌乱的锅。想想你的代码的执行以及它是如何发生的。
关于javascript - jQuery 模态确认对话框未提交表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6905819/