为什么我无法在jQuery UI对话框中触发提交按钮?

16

编辑:

有些人建议直接在表单上调用submit。但这不是我想要的。我想要的是,能够在input type='submit'上调用click()事件,并像通常一样提交表单。jQuery UI对这种正常行为似乎产生了干扰。请查看我创建的jsFiddle链接,因为问题可以在其中重现。


(首先,我已经在StackOverflow上看到了类似的问题,但答案在我的情况下不起作用:jQuery UI带有ASP.NET按钮后台提交

期望的行为:

在我的页面上,我有一个隐藏的字段和一个提交按钮(通过CSS隐藏)。我想使用JavaScript编程方式点击此按钮,从而导致提交表单。最重要的是....我想从jQuery UI Dialog内部触发所有这些内容。基本上,用户将在jQuery UI对话框中进行选择,从而导致整个页面被提交并重新加载。

问题陈述

这样触发按钮点击通常很好地提交表单。但是,当在jQuery UI Dialog中触发动作时,它会失败。

正如您在我的jsFiddle代码中所看到的那样,我在提交按钮上调用了jQuery的click()函数....但表单实际上并没有提交!JavaScript确实点击了该按钮,但“表单提交行为”本身并未发生。页面未被发布。

我认为jQuery UI对我试图以编程方式单击的按钮的表单提交行为产生了干扰。

我想编程触发按钮单击的原因:

我不能将位于对话框内部的按钮本身作为提交按钮。在我的情况下,我创建了一个可重用的JavaScript控件,包装了一个jQuery UI对话框。此JS控件允许用户选择员工。但是,当选择员工时,期望的行为不会总是是:表单提交。(有时我可能只想在页面上显示选定的员工而不执行提交。)

其他细节:

此问题不特定于ASP.NET,但以下是一些附加详细信息,以帮助解释我为什么要进行所有这些尝试。我正在使用.NET 4.5编写ASP.NET Web Forms应用程序。我已经开始在我的页面中更多地使用JavaScript,但在这个特定的页面上,我想触发对服务器的实际回传,以便我可以处理来自ASP.NET页面生命周期的按钮单击事件并填充GridView。这就是为什么我想能够使用JavaScript单击asp:button,反过来导致表单提交。

最重要的是......亲自尝试--->请参见下面的jsFiddle链接.....

再次强调,此问题与ASP.NET无关。我已经能够在JsFiddle上使用常规HTML和jQuery UI重现同样的问题。以下是JsFiddle链接:

http://jsfiddle.net/fENyZ/18/

如您在代码中所看到的,我已尝试使用将jQuery UI Dialog通过jQuery DOM操作移动到表单内部的“修复”方法。这似乎并没有解决问题。

谢谢!我感激任何帮助!

<html> <head></head> <body> <form action="http://www.google.com/index.html" method="post"> <input type="button" value="Open jQuery dialog" id="btnOpenDialog" /> <br /><br /><br /> The button below submits the form correctly if you click it.<br /> However, when I try to trigger click() event on this button <u>from within the jQuery UI Dialog above</u> then the form <b>fails to be submitted. </b><br /> <input type="submit" value="Submit Form" id="btnSubmitForm" /> <input type="hidden" id="hdnEmployeeChosen" value="" /> </form> <div id="divPopup" class="dialogClass" style="display: none;"> Picking an employee below <b>ought to</b> cause the form to submit, but sadly it does not... <br /><br /> <div class="divOptions"> <input type="button" value="Pick" class="pickButton" employeeName="Weird Al" /> Weird Al Yankovic </div> <div class="divOptions"> <input type="button" value="Pick" class="pickButton" employeeName="Dracula" /> Count Dracula </div> <div class="divOptions"> <input type="button" value="Pick" class="pickButton" employeeName="David" /> David Copperfield </div> </div> </body>

JavaScript

$(document).ready(function ()
{
    var jqueryDialog = $('#divPopup')
                .dialog({
                    autoOpen: false,
                    modal: true,
                    title: 'My Dialog',
                    width: 300,
                    height: 300,
                    draggable: false,
                    resizable: false
                });

    // This "fix" does not appear to help matters..........
    jqueryDialog.parent().appendTo($("form:first"));

    $('#btnOpenDialog').click(function () {
        jqueryDialog.dialog('open');    
    });    

    $('.pickButton').click(function () {

        // Put picked value into hidden field
        var pickedEmployee = $(this).attr('employeeName');
        $('#hdnEmployeeChosen').val(pickedEmployee);

        // Try to cause a submit (ASP.NET postback in my case)        
        // THIS PART DOES NOT WORK.................
        $('#btnSubmitForm').click();

        //alert($('#hdnEmployeeChosen').val());
    });    

});

CSS

:CSS是层叠样式表的缩写,用于设置网页的样式和布局。它可以控制文本、颜色、背景、边框等元素的外观,并通过盒模型来控制元素的位置和尺寸。
form {
margin: 5px;
    border: 1px solid black;
    background-color: #EEE;
    padding: 15px 5px;
}

.dialogClass {
 border: 1px solid black;
padding: 5px;
margin: 5px;
    background-color: LightBlue;
    font-size: 14px;
}

.pickButton {
  margin-right: 5px;   
}

.divOptions {
   margin-bottom: 3px;   
}
13个回答

6

我遇到了类似的问题,我能够执行正确的提交按钮步骤,但是表单就是无法提交。在调试jquery对话框代码时,没有找到它如何阻止事件传播的原因,所以我决定在提交前隐藏对话框,这很明显。在你的fiddle上也可以使用: http://jsfiddle.net/Q4GgZ/1/

jqueryDialog.dialog('close'); // <- THIS WORKS
$('#btnSubmitForm').click();

3
根据jquery-ui模态对话框的文档:“如果设为true,则对话框将具有模态行为;页面上的其他项目将被禁用,即不能与之交互。模态对话框在对话框下创建一个遮罩层,但在其他页面元素上方。”-- 文档没有解释"disabled"的实际含义。它的含义是,在对话框打开时,位于遮罩层下方的任何内容都将被禁用事件。 setTimeout是解决此问题的另一种方法,因为当它执行时,对话框已关闭,此时事件不再被禁用。 - Joe Phillips
不确定他们的意思是什么。在使用jQuery之前,我通过让一个遮罩层拦截所有的点击事件,并字面上将“disabled”属性应用于输入框/选择框/按钮等来实现自己的模态框,以防止切换选项卡。表单元素本身不支持禁用属性,所以我仍然很好奇他们使用的机制是什么。仍然没有机会进行更多研究。 - LouD

5

我曾经遇到同样的问题,以下建议对我有用:

  1. 将对话框附加到表单中 $(this).parent().appendTo("form:first");
  2. 在对话框的 open 选项中将对话框附加到表单中

感谢Homam和他在另一个问题中的评论

请参见下面的JavaScript代码:

    var jqueryDialog = $('#divPopup')
        .dialog({
            autoOpen: false,
            modal: true,
            title: 'My Dialog',
            width: 300,
            height: 300,
            draggable: false,
            resizable: false,
            open: function() {
                $(this).parent().appendTo('form:first');
            }
        });

我发现最好在创建对话框后立即调用$('#divPopup').parent().appendTo('form:first');,而不是等到通过open方法打开它,否则ASP.NET WebForms无法看到控件以设置它们的值。 - Matthew Lock

2

正如LouD所提到的,解决方法是在“点击”按钮之前关闭对话框。至于为什么这样做可以解决问题,需要深入研究JQuery UI源代码。在1.8.9版本中,模态覆盖层的代码如下:

events: c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","), function (a) {
    return a + ".dialog-overlay"
}).join(" "),

...

c(document).bind(c.ui.dialog.overlay.events, function (d) {
    if (c(d.target).zIndex() < c.ui.dialog.overlay.maxZ) return false
})

它对于所有“下方”元素的输入事件都返回false(基本上等同于preventDefault())。它不仅是一个巨大的div,通过“覆盖”它来防止用户点击其他内容。它也手动阻止所有输入事件,无论是用户还是您的JS生成的。

关闭模态对话框会销毁遮罩层,允许您的JS点击事件完全传播,并提交表单。


2
如果有人还在寻找答案,这里有一些对我有用的东西。
setTimeout("$('#" + id + "').click();", 0);
id是提交按钮点击事件的e.currentTarget.id。将该id传递给必须触发单击事件的方法。
.trigger("click")不能触发postback,但上述代码可以。

1

给你的表单分配一个id属性:

<form id="myForm" action="http://www.google.com/index.html" method="post">

然后提交表单:

$('.pickButton').click(function (e) {
  e.preventDefault();
  $('#myForm').submit();
  // more code
}

2
附加细节部分中,我提到我正在尝试使用ASP.NET的页面生命周期和后端按钮点击事件来处理提交操作。我使用ASP.NET并不重要,但它解释了为什么我想要实际使用提交按钮来引发后台的回发。仅仅在表单元素上执行提交操作是不足以触发代码后台的按钮点击事件的。这就是为什么我试图将我的问题集中在:如何使用提交按钮来实现所有这些操作。 - ClearCloud8

0

我遇到了一个非常类似的问题,但是由于这个问题让我浪费了一些时间,所以我把它发表出来供未来的读者参考。

这段代码存在一些问题:

  1. 如果对话框是模态的,似乎无法触发对话框外其他元素的事件。如果你将对话框设置为 modal:false 选项,则触发器将正常工作。但我希望对话框是模态的,所以这个解决方案不可行。

  2. 由于对话框是模态的,你必须将按钮放在对话框内。你可以将其隐藏并通过你的 classed 按钮触发。我修改了 JavaScript 部分,并在 fiddle 上尝试过,适用于你的情况。

HTML

<form action="http://www.google.com/index.html" method="post">

    <input type="button" value="Open jQuery dialog" id="btnOpenDialog" />
    <br /><br /><br />

    The button below submits the form correctly if you click it.<br />
    However, when I try to trigger click() event on this button <u>from within the jQuery UI Dialog above</u> then the form <b>fails to be submitted.
    </b><br />


    <input type="hidden" id="hdnEmployeeChosen" value="" />            

    <div id="divPopup" class="dialogClass" style="display: none;">
    Picking an employee below <b>ought to</b> cause the form to submit, but sadly it does not...
    <br /><br />

    <div class="divOptions">
        <input type="button" value="Pick" class="pickButton" employeeName="Weird Al" />
        Weird Al Yankovic
    </div>
    <div class="divOptions">            
        <input type="button" value="Pick" class="pickButton" employeeName="Dracula" />
        Count Dracula
    </div>
    <div class="divOptions">          
        <input type="button" value="Pick" class="pickButton" employeeName="David" />
        David Copperfield
    </div>     

       <input type="submit" value="Submit Form" id="btnSubmitForm" style="display:none"/>  
</div>

</form>    




</body>

JavaScript

$(document).ready(function ()
{
var jqueryDialog = $('#divPopup')
            .dialog({
                autoOpen: false,
                modal: true,
                title: 'My Dialog',
                width: 300,
                height: 300,
                draggable: false,
                resizable: false
            });

// This "fix" does not appear to help matters..........
jqueryDialog.parent().appendTo($("form:first"));

$('#btnOpenDialog').click(function () {
    jqueryDialog.dialog('open');    
});    

$('.pickButton').click(function () {

    // Put picked value into hidden field
    var pickedEmployee = $(this).attr('employeeName');
    $('#hdnEmployeeChosen').val(pickedEmployee);

    console.log("click button dialog");
    // Try to cause a submit (ASP.NET postback in my case)        
    // THIS PART DOES NOT WORK.................
    $('#btnSubmitForm')[0].click();

    console.log("after click");        
    //alert($('#hdnEmployeeChosen').val());
});    

});

你可以在这里看到fiddle 链接


0
这个问题的简单解决方案是在打开对话框后设置提交事件不需要在提交事件触发之前关闭对话框。
当使用.open()方法时,对话框叠加在上面时禁用所有事件。因此,请在打开对话框后设置您需要的事件。
$('#btnOpenDialog').click(function () {
        jqueryDialog.dialog('open');   
     // now setup events 
        $('#btnSubmitForm').on('click', function() {
            // process submit event 
        });
}); 

0

因为它复制了多个对象,所以你可以使用:$('[id="btnCreate"]').last().trigger('submit');

last方法获取最后一个元素。

你可以更新$('#btnSubmitForm').click();

尝试这样做:$('[id="btnSubmitForm"]').last().trigger('click');

$('[id="btnSubmitForm"]')获取所有相同ID的btnSubmitForm。

例如:

$("#dialog").dialog({
            autoOpen: false,
            //maxWidth: 600,
            //maxHeight: 500,
            minWidth: 580,
            width: 580,
            height: 500,
            title: "titleDemo",
            show: {
                effect: "blind",
                duration: 1000
            },
            hide: {
                effect: "explode",
                duration: 1000
            },
            modal: true,
            buttons: {
                "Create": {
                    text: "OK",
                    id: "btnCreates",
                    click: function (event) {
                        $('[id="btnCreate"]').last().trigger('submit');
                    }
                },
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });

我尝试了你关于使用last()的想法,但情况并没有改善。请查看我的更新后的jsFiddle... http://jsfiddle.net/fENyZ/28/ - ClearCloud8
1
好的,我尝试了jsFiddle...并且我看到警报弹出了...但是在最后一个说“提交”的警报上...它实际上没有提交表单。这就是问题的根源。 - ClearCloud8

0

我没有看到提交按钮的点击事件的代码。

而不是

$('#btnSubmitForm').click();

尝试
$('form').submit();

或者在提交按钮的点击事件处理程序中提交表单。


谢谢回复。如果您能看到我对user1757786答案的评论,那就太好了。我需要让按钮本身触发表单提交。我知道我可以获取表单并手动提交它,但这不是理想的方法。我的问题的重点是找出如何使提交按钮本身像应该一样工作。此外,提交按钮不需要任何代码...它的类型为“submit”,因此它会导致表单提交。尝试在jsFiddle中手动单击它并查看它是否提交。 - ClearCloud8

0
提交按钮正在被点击。我在您的脚本中添加了以下代码...
$("#btnSubmitForm").on("click", function() {
    console.log("submit!");
});

这表明按钮已被点击。

正如Sushanth所说,使用表单的submit()方法,或者如果您想触发asp.net的postback,则可以查看__doPostBack()

如何使用__doPostBack()


感谢回复。正如我所提到的,我知道按钮确实被“点击”了……但问题在于,按钮没有执行它通常会执行的表单提交操作。这非常奇怪,因为只有预期行为的一半发生了。在您上面的示例中,当单击按钮时,console.log确实发生了......然而......表单提交没有发生。如果您进入jsFiddle并手动单击我放置在那里的提交按钮,您将看到它可以正常提交。(Sushanth的解决方案不能解决我提出的问题……您可以看到我在那里的评论。) - ClearCloud8
昨天,我尝试使用__doPostBack()来触发表单提交...但那似乎也不起作用。这就是为什么我通过jsFiddle仅使用HTML和jQuery UI重新创建了这个问题。这样人们就可以看到它与ASP.NET无关。这是一个普遍存在的问题。我认为如果能找到解决这个通用问题的方法,那么我就能将其应用到我的具体情况中(在这种情况下,是ASP.NET)。 - ClearCloud8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接