[英]jQuery Modal Confirmation Dialog Not Submitting Form
当用户按下编辑表单上的删除按钮时,我试图弹出一个确认模式。 模式弹出很好,但是当jQuery应该提交表单时,它没有做任何事情。 我删除了一个type =“button”,因为当它是类型提交时,模态函数不会阻止进程,它只是立即删除用户。
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库将事件绑定到元素,而不是将javascript函数调用混合到HTML中? 在文档就绪语句之后,您应该在<script>
标记中执行类似的操作。
$("#delete_btn").click(function(e){
/*Code that runs on click of the "delete_btn" ID tag*/
});
如果您不熟悉jQuery选择器和事件,那么请从这里开始阅读 。
您应该执行此操作的另一个原因是,如果文档未正确/完全加载,以防止文档损坏您的用户。
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的
Hokay,所以,这是你的功能:
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.
哎呀。 看起来你有一个未定义的变量,这意味着它现在是全局的。 全局变量很糟糕,它们会破坏范围并使代码以奇怪的方式运行。
我们需要解决这个问题。 您应该始终在本地范围内声明局部变量。 这意味着放入一个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,以便其他人更方便地为您提供帮助。
这是我们迄今为止所做的修订的jsFiddle。 如果你在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之间的混淆。 表格的外观如何:
关键点:
你的形式正在发生一些奇怪的事情。
这是一个javascript了解如何提交的表单: http : //jsfiddle.net/YS8uW/2/
这是javascript尝试提交您的表单(剥离到简单): http : //jsfiddle.net/LfDXh/
这有什么不同?
让我们看看你做过的事情,给出了提交给某事的ID: http : //jsfiddle.net/fdLfC/
当我们不使用它作为ID时会发生什么? http://jsfiddle.net/fdLfC/1/
这就像给它一个提交ID不会让你调用提交。 一个正确的解释是,你重写了它,因为dom在你分配了ID和Name时就做了,它试图调用元素。
你可以看到这个,如果你打开一个调试器或什么,它会给你一个警告:
TypeError:对象#的属性'submit'不是函数
非常感谢@MattMcDonald将我链接到这个资源 , 该资源解释了如何处理,以及为什么NAME和ID属性覆盖了内置的HTML DOM方法。
做我说的其他事情。 免责声明:每个人都要对我发动战争,说你应该做所有这些事情并不是绝对的,我同意,但我认为这篇文章已经足够长了,我们都同意做这些事情是代码中的一个进步质量,而不是倒退。 这取决于你最后,但试着避免将东西混合成一个巨大的杂乱的锅。 考虑一下代码的执行情况以及代码的执行情况。
如果您确定它附加隐藏的输入,那么问题必须是使用重复的ID。 按钮和隐藏输入具有相同的ID。 让它们与众不同,然后重试。
不要问我它工作的原因,我可以告诉你的是,在完成这个和那个并且撕掉代码的每个部分之后, 我终于让它工作了 。 点击下面的链接查看演示
http://jsfiddle.net/praveen_prasad/KaK5A/4/
我所做的更改是:从表单中的提交按钮中删除id
和name
属性
例:
<input type="submit" value="Save" name="submit" id="submit"/>
上面改为下面
<input type="submit" value="Save" />
注意对于JsFiddle演示:当您单击模态上的删除用户时,表单将提交。 jsfiddle将说“错误404”,因为它不会找到您发布表单的链接。 打开firebug并看到它实际发布到正确的url。
"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); // HERE ----------------
tmpElm.appendTo(form);
form.submit();
return true;
}
在指定地点,不应该是:
tmpElm.value(true);
要么
tmpElm.attr('value', 'true');
我发现通过带有序列化表单值的jQuery ajax确认处理我的表单提交时不那么困惑。 它还有一个额外的好处,即避免从<form>
标签内的按钮提交不需要的表单。 所以,它看起来像这样:
<form id="edit_user_form">
...
<button id="submit_btn">Submit</button><br />
<button id="cancel_btn">Cancel</button><br />
<button id="delete_btn">Delete</button>
...
</form>
然后是javascript:
$('#delete_btn').click(function() {
$('#dialog-modal').dialog({
autoOpen: false,
width: 400,
modal: true,
resizable: false,
buttons: {
"Cancel": function() {
$(this).dialog("close");
return false;
},
"Delete User": function() {
$.ajax({
url: "/admin/edit-user",
type: "POST",
data: $('#edit_user_form).serialize(),
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred: " + errorThrown);
},
success: function(){
//Notify of success, redirect, etc.
}
});
}
}
});
});
所以,它仍然通过POST提交。 它现在可以异步(或不是)发生。您可以在不改变页面的情况下“成功”,或者根据需要重定向。 我使用“调度程序”页面提交到我的面向对象的框架,然后将输出返回给PHP调度程序以进行json_encoded并作为字符串回显,以便成功使用AJAX调用。 使用这种模式,我只需要有一个页面吐出纯文本,其余的可以驻留在我的OO类中,不能通过ajax直接调用它而不做一些严重的破坏(使用xajax)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.