SimpleModal打破了ASP.Net Postbacks

时间:2008-08-26 23:19:48

标签: asp.net javascript jquery postback simplemodal

我在ASP.Net项目中使用jQuerySimpleModal来为Web应用程序创建一些不错的对话框。不幸的是,模态对话框中的任何按钮都不能再执行回发,这是不可接受的。

我找到了workaround的一个来源,但对于我的生活,我无法让它工作,主要是因为我没有完全理解所有必要的步骤。

我也有一个解决方法,即替换回发,但它很难看,可能不是最可靠的。我真的想让回发再次运作。有什么想法吗?

更新:我应该澄清一下,回发不起作用,因为用于执行回发的Javascript在某种程度上已经破坏,所以当点击按钮时根本不会发生任何事情。

10 个答案:

答案 0 :(得分:32)

你们两个都走在正确的轨道上。我意识到SimpleModal会将对话框附加到正文,该正文位于ASP.Net的<form>之外,它会破坏功能,因为它无法找到元素。

要解决此问题,我只修改了SimpleModal源代码,将eveything追加到'form'而不是'body'。当我创建对话框时,我还使用persist: true选项,以确保按钮保持打开和关闭。

感谢大家的建议!

更新:版本1.3在配置中添加了appendTo选项,用于指定应将模式对话框附加到哪个元素。 Here are the docs

答案 1 :(得分:6)

所有标准的ASP.NET回发都可以通过在页面上调用__doPostBack javascript方法来工作。该函数提交表单(ASP.NET每页真的只喜欢一个表单),其中包含一些隐藏的输入字段,其中所有的viewstate和其他善良都存在。

从表面上看,我在SimpalModal中看不到任何会搞砸页面形式或任何标准隐藏输入的内容,除非该模式的内容碰巧来自HTTP GET到ASP.NET页面。这将导致两个ASP.NET表单呈现为一个DOM,并且几乎肯定会搞砸__doPostBack函数。

您是否考虑过使用ASP.NET AJAX ModalPopup control

答案 2 :(得分:4)

Web浏览器不会POST任何已禁用或隐藏的表单元素。

所发生的事情是:

  1. 用户点击对话框中的按钮。
  2. 该按钮调用SimpleModal的close()方法,隐藏对话框和按钮
  3. 客户端POST表单(没有按钮的ID)
  4. ASP.NET框架无法确定单击了哪个按钮
  5. 您的服务器端代码无法执行。
  6. 解决方案是在客户端做任何你需要做的事情(在这种情况下关闭对话框),然后自己调用__doPostback()。

    例如(其中“dlg”是客户端SimpleModal对话框引用):

    btn.OnClientClick = string.Format("{0}; dlg.close();",
                            ClientScript.GetPostBackEventReference(btn, null));
    

    这应隐藏对话框,提交表单,并调用您为该按钮提供的任何服务器端事件。

    @丹

      
        

    所有标准的ASP.NET回发都可以通过在页面上调用__doPostBack javascript方法来实现。

      

    asp:Buttons不调用__doPostback(),因为HTML输入控件已经提交了表单。

答案 3 :(得分:2)

被这一个抓住了 - 非常感谢tghw和其他贡献者在附加形式而不是身体修复。 (由1.3版本的属性解决)

btw:如果有人需要以编程方式从.net关闭对话框 - 你可以使用这种语法

private void CloseDialog()
{
    string script = string.Format(@"closeDialog()");
    ScriptManager.RegisterClientScriptBlock(this, typeof(Page), UniqueID, script, true);
}

其中,openialog的javascript就是这样......

    function closeDialog() {
        $.modal.close();
    }

答案 4 :(得分:0)

我发现以下工作而不修改simplemodal.js:

function modalShow(dialog) {

    // if the user clicks "Save" in dialog
    dialog.data.find('#ButtonSave').click(function(ev) {
        ev.preventDefault();

        //Perfom validation                

        // close the dialog
        $.modal.close();

        //Fire the click event of the hidden button to cause a postback
        dialog.data.find('#ButtonSaveTask').click();
    });

    dialog.data.find("#ButtonCancel").click(function(ev) {
        ev.preventDefault();
        $.modal.close();
    });
}          

因此,不是使用对话框中的按钮来导致回发,而是阻止他们提交,然后在表单中找到隐藏按钮并调用其click事件。

答案 5 :(得分:0)

FWIW,我已经更新了blog post you pointed to并进行了澄清,转载于此处 - 推理&amp;其他详细信息在博客文章中:

解决方案(截至我午餐前的最后一次检查):

      
  1. 覆盖对话框的onClose事件,并执行以下操作:     
            
    1. 调用对话框的默认关闭功能
    2.       
    3. 将对话框div的innerHTML设置为单个&amp; nbsp;
    4.       
    5. 劫持__doPostBack,将其指向一个新函数newDoPostBack
    6.        

      从我在网上看到的一些评论来看,第1点需要一些澄清。不幸的是,我不再和同一个雇主在一起,也无法访问我使用的代码,但我会尽我所能。首先,您需要通过定义一个新函数来覆盖对话框的onClose函数,并将对话框指向它,如下所示:

        
      $('#myJQselector').modal({onClose: mynewClose});
          
      • 调用对话框的默认关闭功能。在您定义的函数中,您应首先调用默认功能(对于您通常覆盖的任何内容,这是最佳实践):
      •   
      • 将对话框div的innerHTML设置为单个&amp; nbsp; - 这不是必需的步骤,如果您不理解,请跳过它。
      •   
      • 劫持__doPostBack,将其指向一个新函数newDoPostBack
        
      function myNewClose (dialog)
        
      {
        
          dialog.close();
        
          __doPostBack = newDoPostBack;
        
      }
          
      1. 编写newDoPostBack函数:
      2.   
        function newDoPostBack(eventTarget, eventArgument)
        {
          
            var theForm = document.forms[0];
          
            if (!theForm)
          
            {
          
                theForm = document.aspnetForm;
          
            }
          
         
          
            if (!theForm.onsubmit || (theForm.onsubmit() != false))
          
            {
          
                document.getElementById("__EVENTTARGET").value = eventTarget;
          
                document.getElementById("__EVENTARGUMENT").value = eventArgument;
          
                theForm.submit();
          
            }
        }
            

答案 6 :(得分:0)

新的Jquery.simplemodal-1.3.js有一个名为appendTo的选项。所以添加一个名为appendTo的选项:'form',因为默认是appendTo:'body',它在asp.net中不起作用。

答案 7 :(得分:0)

有同样的问题,但{appendTo:'form'}导致模式弹出窗口完全错误(好像我有一个CSS问题)。

原来我在上面构建的模板包括在页面上放置其他表单。一旦我设置{appendTo:'#aspnetForm'}(默认的Asp.net表单ID),一切都很好(包括回发)。

答案 8 :(得分:0)

除了tghw的回答,这篇优秀的博客帖子帮助了我:jQuery: Fix your postbacks in Modal forms - 特别是BtnMike的评论:“你也不能在你的asp:按钮上设置CssClass =”simplemodal-close“。在课堂上取消这个对我来说并不明显。

-John

答案 9 :(得分:-1)

如果您不想修改SimpleModal源。 试试这个..

调用modal()方法后,添加:

$("#simplemodal-overlay").appendTo('form');
$("#simplemodal-container").appendTo('form');

SimpleModal插件将两个加到你的标记中。

  1. 'simplemodal-overlay'为背景
  2. 'simplemodal-container'包含你作为弹出模式的div。