繁体   English   中英

jQuery模态确认对话框未提交表单

[英]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');
    }

这里发生了什么? 第一步,您应该尝试使用工具来衡量代码质量。 两个流行的是JSHintJSLint的 您不需要按照他们所说的内容进行操作,因为这是编写代码的唯一方法,但它在查找由于小错误而导致的错误方面非常有用。 我喜欢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之间的混淆。
  • 我们点击这个表单提交按钮? 你有很多,jQuery不会猜测并希望最好的。

表格的外观如何:

w3解释了什么是形式和事物的目的。

关键点:

  • 名称与值配对
  • 单击提交按钮,未单击提交按钮。
  • 可以基于NAME和ID属性来导航DOM

你的形式正在发生一些奇怪的事情。

这是一个javascript了解如何提交的表单: http//jsfiddle.net/YS8uW/2/

这是javascript尝试提交您的表单(剥离到简单): http//jsfiddle.net/LfDXh/

这有什么不同?

  • 你到处都有ID。
  • 您使用关键字作为名称

让我们看看你做过的事情,给出了提交给某事的ID: http//jsfiddle.net/fdLfC/

当我们不使用它作为ID时会发生什么? http://jsfiddle.net/fdLfC/1/

啊。 这太奇怪了。

这就像给它一个提交ID不会让你调用提交。 一个正确的解释是,你重写了它,因为dom在你分配了ID和Name时就做了,它试图调用元素。

你可以看到这个,如果你打开一个调试器或什么,它会给你一个警告:

TypeError:对象#的属性'submit'不是函数

远离使用关键词来表示其他内容,你不会陷入这些奇怪的陷阱。

非常感谢@MattMcDonald将我链接到这个资源该资源解释了如何处理,以及为什么NA​​ME和ID属性覆盖了内置的HTML DOM方法。

做我说的其他事情。 免责声明:每个人都要对我发动战争,说你应该做所有这些事情并不是绝对的,我同意,但我认为这篇文章已经足够长了,我们都同意做这些事情是代码中的一个进步质量,而不是倒退。 这取决于你最后,但试着避免将东西混合成一个巨大的杂乱的锅。 考虑一下代码的执行情况以及代码的执行情况。

如果您确定它附加隐藏的输入,那么问题必须是使用重复的ID。 按钮和隐藏输入具有相同的ID。 让它们与众不同,然后重试。

不要问我它工作的原因,我可以告诉你的是,在完成这个和那个并且撕掉代码的每个部分之后, 我终于让它工作了 点击下面的链接查看演示

http://jsfiddle.net/praveen_prasad/KaK5A/4/

我所做的更改是:从表单中的提交按钮中删除idname属性

例:

<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM