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

标签 javascript jquery jquery-ui modal-dialog forms

当用户按下编辑表单上的删除按钮时,我试图弹出一个确认模式。模态弹出很好,但是当 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 .
  • You can find all the events here .
  • You can find all the selectors 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');
        }
    
    这里发生了什么?第一步,您应该尝试使用工具来衡量代码质量。两个流行的是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.
    
    哎呀。看起来你在那里有一个 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;
    }
    
  • 你为什么要声明self?你永远不会使用它一次。让我们摆脱它。
  • 您可以使用称为链接的东西,这完全取决于您。有些人讨厌它。
  • 您将一个全新的输入添加到表单中,看起来像是一个选择,我不确定这是否明智。我建议更改普通输入的值,或使用另一种模式,这可能会导致很多问题,但就问题而言,我认为这样做是出于所有正确的原因。但是要小心,如果有人双击提交,则该输入会出现两次。
  • form是 DOM 中使用的保留词,您应该避免使用该词,以免混淆您的变量和 DOM API。
  • 我们在这里单击哪个表单提交按钮?你有很多,jQuery 不会猜测和希望最好的。

  • 表单的外观:
    The w3 explains what forms are and the purpose of things.
    关键点:
  • 名称与值配对
  • 点击的提交按钮被发送,未点击的提交按钮不被发送。
  • DOM 可以根据 NAME 和 ID 属性导航

  • 你的表格里发生了一些奇怪的事情。
    这是一个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/

    相关文章:

    javascript - jQuery .hover() 自动返回到之前的状态

    javascript - jQuery 模态和加载问题

    javascript - jquery ui 当我单击可放置项目时如何获取可拖动项目的 id

    JavaScript 对象定义属性不起作用

    javascript - 如何使用 for 循环制作 JavaScript 幻灯片

    javascript - 为什么 jQuery.each 不循环所有项目?

    javascript - 无法将变量获取到 Jquery 函数中

    javascript - 如何从Java服务器读取JavaScript中的数据?

    javascript - JSON.stringify 根据两个不同的页面上下文表现不同

    jquery - 为什么 jQuery animate 不能与 cssHooks 一起使用?