第一次打开jquery对话框时的奇怪问题(在asp.net gridview中)

时间:2012-06-27 14:03:18

标签: jquery asp.net

我在更新面板中有一个gridview。 gridview中的一个字段是ASP.net linkbutton,如下所示:

 <ItemTemplate>
       <asp:LinkButton ID="hlSortOrder" runat="server" CssClass="hlDialog" OnClick="LoadLog"
        Text='<%# DataBinder.Eval(Container, "DataItem.SortOrder") %>'></asp:LinkButton>
  </ItemTemplate>

当有人点击链接按钮时,我会调用我创建的名为OnClick的{​​{1}}方法。 LoadLog如下所示:

LoadLog

基本上它获取了网格视图行的句柄,从数据库中提取一些数据并将其分配给gvLog源。之后注意到最后一行:

protected void LoadLog(object sender, EventArgs e) { GridViewRow gr = (GridViewRow)((DataControlFieldCell)((LinkButton)sender).Parent).Parent; Label l = (Label)gr.FindControl("lblID"); DataSet ds; ds = BL.GetRunoffAnswerLog(Convert.ToInt64(l.Text)); if (ds != null) { if (ds.Tables[0].Rows.Count == 0) { gvLog.Visible = false; gvLog.DataSource = null; lblRowsCount.Text = "No log for this record!"; } else { lblRowsCount.Text = ds.Tables[0].Rows.Count.ToString() + " row(s) found for this record."; gvLog.DataSource = ds.Tables[0]; gvLog.DataBind(); gvLog.Visible = true; } } ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "openDialog", "$('#dialog').dialog({draggable: true, modal: true, height: 500, width: 750, title: 'Log', open: function (type, data) {$(this).parent().appendTo('form');}});", true); }

我必须这样做才能打开我的对话框。当我第一次点击gridview中的一行时:

enter image description here

注意它只是真正显示标题......很奇怪。但是一旦我再次点击同一行,它就会显示整个对话框:

enter image description here

它只发生在第一次点击,如果我一直点击不同的行,它工作正常。我应该补充一点,我必须添加以下jquery代码:

ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "openDialog", "$('#dialog').dialog({draggable: true, modal: true, height: 500, width: 750, title: 'Log', open: function (type, data) {$(this).parent().appendTo('form');}});", true);

基于此讨论:jQuery $(document).ready and UpdatePanels?

如果我在回复发生的那一刻没有那段代码,那么这个对话框所在的整个div总会显示在我的页面上,我不想要那个......

正如下面的一位成员所提到的那样。我相信正在发生的事情是你第一次点击链接按钮,客户端事件首先发生,打开实际的打开对话框,即使我在服务器端代码中引发此事件...正如你在上面看到的那样,只有当你点击单击“LoadLog”事件,我注册了这个jquery opendialog。但看起来这仍然是第一次打开对话框,一旦你第二次单击它就会显示数据。

4 个答案:

答案 0 :(得分:3)

我遇到了很多关于jQuery awesomeness和UpdatePanels的问题。试试这种方法:

  1. 将用于对话框的div放在更新面板之外。不要在后面的代码中创建对话框。而是在页面加载时创建对话框。由于您的对话框在updatepanel之外,因此不会被破坏。确保不要自动打开它。
  2. 在对话框div中添加一个额外的div来保存您的内容。
  3. 创建一个javascript函数
    • 清除对话框中任何以前内容的内容div的内容
    • gvLog控件附加到对话框内容div,例如$('#dialogContent').append($('#<%= gvLog.ClientID %>'));
    • 显示对话框
  4. 现在在您的代码中调整RegisterClientScriptBlock来调用这个新的javascript函数。
  5. 示例代码
    代码背后:

    public partial class _Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                //load in some dummy data
                Dictionary<int, string> vals = new Dictionary<int, string>()
                {
                    {1, "ONE"},
                    {2, "TWO"},
                    {3, "THREE"},
                    {4, "FOUR"},
                    {5, "FIVE"},
                    {6, "SIX"}
                };
    
                gvData.DataSource = vals;
                gvData.DataBind();
            }
        }
    
        protected void LoadLog(object sender, EventArgs e)
        {
            LinkButton lb = (LinkButton)sender;
            var key = lb.CommandArgument;
    
            Random r = new Random();
            Dictionary<int, int> dict = new Dictionary<int, int>();
    
            for (int i = 0; i <= r.Next(5, 20); i++)
            {
                dict.Add(r.Next(), r.Next());
            }
    
            gvLog.DataSource = dict;
            gvLog.DataBind();
    
            //show log in dialog on client
            ScriptManager.RegisterStartupScript(up, up.GetType(), "openDialog", "showLog();", true);
        }
    }
    

    设计师代码:

    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <script src="Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
        <script src="Scripts/jquery-ui-1.8.21.custom.min.js" type="text/javascript"></script>
        <link href="ui-lightness/jquery-ui-1.8.21.custom.css" rel="stylesheet" type="text/css" />
    
        <script type="text/javascript">
            $(function () { 
                //setup dialog
                $('#dialog').dialog({draggable: true, 
                                    modal: true, 
                                    height: 500, 
                                    width: 750, 
                                    title: 'Log',
                                    autoOpen: false});
            });
    
            function showLog() {
                //clear any old log data
                $('#dvContent').empty();
                //append current log
                $('#<%= gvLog.ClientID %>').appendTo($('#dvContent'));
                //show dialog
                $('#dialog').dialog('open');
            }
        </script>
    </head>
    
    <body>
        <form id="form1" runat="server">
        <asp:ScriptManager ID="sp" runat="server" />
        <div>
            <asp:UpdatePanel ID="up" runat="server">
                <ContentTemplate>
                    <asp:GridView ID="gvData" runat="server">
                        <Columns>
                            <asp:TemplateField>
                                <ItemTemplate>
                                    <asp:LinkButton ID="lbShowLog" runat="server" Text="Show Log" 
                                        OnClick="LoadLog" CommandArgument='<%# Eval("Key") %>' />
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
    
                    <div style="display:none;">
                        <asp:GridView ID="gvLog" runat="server">
                        </asp:GridView>
                    </div>
                </ContentTemplate>
            </asp:UpdatePanel>
        </div>
    
        <div id="dialog" style="display:none;">
            <div id="dvContent">
    
            </div>
        </div>
        </form>
    </body>
    </html>
    

答案 1 :(得分:0)

请参阅this

尝试添加对$('#dialog').dialog('open')

的调用

您第一次拨打$('#dialog').dialog([Parmas])可能会创建它但不能打开它。

这样的事情:

 ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "openDialog", "$('#dialog').dialog({draggable: true, modal: true, height: 500, width: 750, title: 'Log', open: function (type, data) {$(this).parent().appendTo('form');}});$('#dialog').dialog('open');", true);

HTH

答案 2 :(得分:0)

在打开对话框之前尝试修改 DOM

在代码中:

ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "openDialog", "$(this).parent().appendTo('form');

在JS中:

$('#dialog').dialog({draggable: true, modal: true, height: 500, width: 750, title: 'Log', true);

答案 3 :(得分:0)

对于您的问题,有一个非常棘手的解决方案可以帮助您避免更新面板和jquery的所有麻烦。

首先,我们不依赖于RegisterClientScriptBlock函数,而是通过隐藏字段完成所有操作。

  1. 创建一个隐藏字段,该字段将标记是否显示该对话框。
  2. 创建一个javascript函数,检查隐藏字段是否有值。 如果隐藏字段有值,则显示show对话框并依赖隐藏字段获取数据,否则不显示对话框,这将解决回发后显示对话框问题。
  3. 将动画扩展程序添加到更新面板
  4. <cc1:UpdatePanelAnimationExtender ID="UpdatePanelAnimationExtender1" TargetControlID="UpdatePanel1" runat="server"> <Animations> <OnUpdated> <Parallel duration="0">
    <ScriptAction Script="YouFunctionCall();" /> </Parallel> </OnUpdated> </Animations> </cc1:UpdatePanelAnimationExtender>

    并在此javascript函数结束时清除隐藏字段。

    那么会发生什么,在回发后javascript将运行以检查标志是否已设置并且它将发现该标志为空并且当您在更新面板内单击时,您的服务器端代码将运行并设置隐藏字段标志和所需的任何其他信息然后更新面板动画扩展器将在更新面板更新后运行javascript函数并将检查隐藏字段并找到它填充数据并将触发显示对话框然后重置标志所以任何其他帖子都不会显示对话框。