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

ash*_*exm 11 javascript forms jquery jquery-ui modal-dialog

当用户按下编辑表单上的删除按钮时,我试图弹出一个确认模式.模式弹出很好,但是当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>
Run Code Online (Sandbox Code Playgroud)

...

<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>
Run Code Online (Sandbox Code Playgroud)

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');
    }
Run Code Online (Sandbox Code Playgroud)

当我检查源代码时,我发现代码正在附加新的隐藏元素,但提交似乎并不想触发.我错过了什么步骤?

Inc*_*ito 26

尝试不同的方式.


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*/
});
Run Code Online (Sandbox Code Playgroud)

如果您不熟悉jQuery选择器和事件,那么请从这里开始阅读.

您应该执行此操作的另一个原因是,如果文档未正确/完全加载,以防止文档损坏您的用户.


CSS

您还完成了这个:style="float:left; margin:0 7px 0 0;"在HTML标记中?这是邪恶的,伙计.只是邪恶.我如何在五个月内维护此代码?

相反,使用CSS.

在您的标签或CSS文件中,您需要一个条目,例如:

.dialogAdjust {
    float: left;
    margin: 0 7px 0 0;
}
Run Code Online (Sandbox Code Playgroud)

然后在你的HTML中你会说:

<span class="ui-icon ui-icon-alert dialogAdjust"></span>
Run Code Online (Sandbox Code Playgroud)

现在,您可以根据自己的内容调整内容.如果你可以在对话框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');
    }
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?第一步,您应该尝试使用工具来衡量代码质量.两个流行的是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.
Run Code Online (Sandbox Code Playgroud)

哎呀.看起来你有一个未定义的变量,这意味着它现在是全局的.全局变量很糟糕,它们会破坏范围并使代码以奇怪的方式运行.

我们需要解决这个问题.您应该始终在本地范围内声明局部变量.这意味着将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>
Run Code Online (Sandbox Code Playgroud)

在寻求帮助时,使用像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;
}
Run Code Online (Sandbox Code Playgroud)
  • 你为什么宣称自己?你永远不会使用它一次.让我们摆脱它.
  • 可以使用一种叫做链接的东西,它真的取决于你.有些人讨厌它.
  • 你为表单添加了一个全新的输入,看起来像是一个选择,我不确定这是明智的.我建议改变正常输入的值,或使用其他模式,这可能会导致很多问题,但为了这个问题,我会想象它是出于所有正确的原因而完成的.但是要小心,如果有人双击提交,那么输入就在那里两次.
  • 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方法.

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

  • 我给了一个upvote,因为他是正确的并且提供了背景,这比仅仅给出答案更有用. (4认同)
  • 我给了你一个upvote,因为你有耐心写下所有这些. (2认同)