【问题标题】:SimpleModal breaks ASP.Net PostbacksSimpleModal 打破 ASP.Net 回发
【发布时间】:2010-09-06 22:46:35
【问题描述】:

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

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

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

更新:我应该澄清一下,回发无法正常工作,因为用于执行回发的 Javascript 在某种程度上已损坏,因此单击按钮时根本没有任何反应。

【问题讨论】:

    标签: asp.net javascript jquery postback simplemodal


    【解决方案1】:

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

    为了解决这个问题,我刚刚修改了 SimpleModal 源以将所有内容附加到 'form' 而不是 'body'。创建对话框时,我还使用了persist: true 选项,以确保按钮在打开和关闭时保持不变。

    感谢大家的建议!

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

    【讨论】:

    • 当我注意到我的 .net 验证控件在关闭并重新打开模式后没有触发时,使用 persist: true 帮助了我。你的回答解决了我的问题,非常感谢! :)
    【解决方案2】:

    所有标准 ASP.NET 回发都通过在页面上调用 __doPostBack javascript 方法来工作。该函数提交表单(ASP.NET 只真正喜欢每页一个表单),其中包括一些隐藏的输入字段,所有视图状态和其他优点都存在于其中。

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

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

    【讨论】:

      【解决方案3】:

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

      所以发生的事情是:

      1. 用户单击对话框中的按钮。
      2. 按钮调用 SimpleModal 的 close() 方法,隐藏对话框和按钮
      3. 客户端 POST 表单(不带按钮 ID)
      4. ASP.NET 框架无法确定单击了哪个按钮
      5. 您的服务器端代码没有被执行。

      解决方案是在客户端上做任何你需要做的事情(在这种情况下关闭对话框),然后自己调用 __doPostback()。

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

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

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

      @丹

      所有标准 ASP.NET 回发都通过在页面上调用 __doPostBack javascript 方法来工作。

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

      【讨论】:

      • 谢谢!我的问题还没有完全解决,但我的 Rails 表单因此默认为非 ajax。我认为当 SimpleModal 重新排列事物时没有附加 jquery-ujs 回调,但看起来浏览器拒绝从隐藏表单发布是问题所在。事后看来完全有道理。
      【解决方案4】:

      被这个抓住了 - 非常感谢 tghw 和 appendto 表单上的所有其他贡献者,而不是 body fix。 (通过1.3版本的属性解决)

      顺便说一句:如果有人需要从 .net 以编程方式关闭对话框 - 您可以使用这种类型的语法

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

      closedialog的javascript哪里是这样的......

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

      【讨论】:

        【解决方案5】:

        在没有修改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();
            });
        }          
        

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

        【讨论】:

          【解决方案6】:

          FWIW,我已经更新了 blog post you pointed to,并在此处进行了澄清,并在此处重新发布 - 推理和其他详细信息在博客文章中:

          解决方案(截至我上次午饭前签到):

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

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

          $('#myJQselector').modal({onClose: mynewClose});
          • 调用对话框的默认关闭函数。在您定义的函数中,您应该首先调用默认功能(对于您通常覆盖的任何内容的最佳实践):
          • 将对话框 div 的 innerHTML 设置为单个   – 这不是必需的步骤,如果您不理解,请跳过它。
          • 劫持 __doPostBack,将其指向一个新函数 newDoPostBack
          function myNewClose (dialog)
          {
              dialog.close();
              __doPostBack = newDoPostBack;
          }
          1. 编写newDoPostBack函数:
          函数 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();
           }
          }
              

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

              遇到了同样的问题,但{appendTo:'form'} 导致模态弹出窗口呈现完全错误(好像我遇到了 CSS 问题)。

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

              【讨论】:

                【解决方案9】:

                除了 tghw 的回答之外,这篇出色的博文也帮助了我:jQuery: Fix your postbacks in Modal forms——特别是 BtnMike 的评论:“你也不能在你的 asp:button 上设置 CssClass=”simplemodal-close”。把它从课堂上取消是我不明显的解决方案。

                -约翰

                【讨论】:

                  【解决方案10】:

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

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

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

                  SimpleModal 插件将两个 this 添加到您的标记中。

                  1. 'simplemodal-overlay' 用于背景
                  2. 'simplemodal-container' 包含您想要作为弹出模式的 div。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-03-31
                    相关资源
                    最近更新 更多