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

时间:2022-11-01 11:04:22

I have a gridview inside an updatepanel. One of the fields in the gridview is an ASP.net linkbutton like so:

我在updatepanel里面有一个gridview。 gridview中的一个字段是ASP.net链接按钮,如下所示:

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

When someone clicks the linkbutton I call the OnClick method that I created called LoadLog. LoadLog looks like this:

当有人点击链接按钮时,我调用我创建的名为LoadLog的OnClick方法。 LoadLog看起来像这样:

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);
        }

Basically it gets a handle of the grid view row, pulls some data back from the database and assigns it to the gvLog source. After that notice the line at the end:

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

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);

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);

I have to do this so that I can open up my dialog box. When I click a row in my gridview ONLY the first time I get this:

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

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

Notice it only really shows the title...weird. But once I click that same row again it shows the entire dialog:

请注意,它只显示标题......很奇怪。但是,一旦我再次单击该行,它将显示整个对话框:

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

It only happens on the first click, if I keep clicking different rows it works fine. I should add that I had to add the following jquery code:

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

 <script type="text/javascript">
        $(document).ready(function () {
            var prm = Sys.WebForms.PageRequestManager.getInstance();

            prm.add_endRequest(function () {
                $("#dialog").hide();
                // re-bind your jQuery events here 
           });
        ....more code...

Based on this discussion: jQuery $(document).ready and UpdatePanels?

基于这个讨论:jQuery $(document).ready和UpdatePanels?

If I do not have that code the minute a post back happens the entire div that this dialog is inside always gets shown on my page and I dont want that...

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

As one of the members below has mentioned. I believe what is happening is the first time you click the linkbutton the client side event is happening first which is opening the actual open dialog, even though I raise this event in server side code...as you see above only when you click the "LoadLog" event click do I register this jquery opendialog. But it appears that this still opens the dialog the first time and once you click it the second time only then is the data shown.

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

4 个解决方案

#1


3  

I have had a lot of issues with jQuery awesomeness and UpdatePanels. Try this approach:

我在jQuery awesomeness和UpdatePanels方面遇到了很多问题。试试这种方法:

  1. Place the div that you are using for your dialog outside of your update panel. Don't create your dialog in code behind. Instead create your dialog on page load. Since your dialog is outside the updatepanel it won't get clobbered. Make sure to not auto-open it.
  2. 将用于对话框的div放在更新面板之外。不要在后面的代码中创建对话框。而是在页面加载时创建对话框。由于您的对话框在updatepanel之外,因此不会被破坏。确保不要自动打开它。

  3. Add an additional div to your dialog div to hold your content.
  4. 在对话框div中添加一个额外的div来保存您的内容。

  5. Create a javascript function that
    • clears the contents of the content div in your dialog of any previous content
    • 清除对话框中任何先前内容的内容div的内容

    • appends the gvLog control to the dialog content div, something like $('#dialogContent').append($('#<%= gvLog.ClientID %>'));
    • 将gvLog控件附加到对话框内容div,类似于$('#dialogContent')。append($('#<%= gvLog.ClientID%>'));

    • shows the dialog
    • 显示对话框

  6. 创建一个javascript函数,清除对话框中内容div的内容,将gvLog控件附加到对话框内容div,如$('#dialogContent')。append($('#<%= gvLog。 ClientID%>'));显示对话框

  7. Now in your code behind tweak the RegisterClientScriptBlock to call this new javascript function.
  8. 现在在你的代码后面调整RegisterClientScriptBlock来调用这个新的javascript函数。

Example Code
Code Behind:

示例代码背后:

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);
    }
}

Designer Code:

<%@ 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>

#2


0  

There is a very tricky solution for your problem that will save you from all the hassle of the update panel and the jquery.

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

First, we will not depend on the RegisterClientScriptBlock function and instead everything will be done through hidden fields.

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

  1. Create a hidden field that will flag if the show dialog to be show or not.
  2. 创建一个隐藏字段,该字段将标记是否显示show对话框。

  3. Create a javascript function that check if hidden field has value or not. If the hidden field had value, display the show dialog and depend on hidden fields to get the data else don't show the dialog, this will fix the problem of the post back show dialog issue.
  4. 创建一个javascript函数,检查隐藏字段是否有值。如果隐藏字段有值,则显示show对话框并依赖隐藏字段获取数据,否则不显示对话框,这将解决post back show对话框问题。

  5. add an animation extender to the update panel
  6. 将动画扩展器添加到更新面板

<cc1:UpdatePanelAnimationExtender ID="UpdatePanelAnimationExtender1" TargetControlID="UpdatePanel1" runat="server"> <Animations> <OnUpdated> <Parallel duration="0">
<ScriptAction Script="YouFunctionCall();" /> </Parallel> </OnUpdated> </Animations> </cc1:UpdatePanelAnimationExtender>

and at the end of this javascript function clear the hidden field.

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

So what will happen, at post back the javascript will run to check if the flag is set or not and it will find that the flag is empty and when you click inside the update panel, your server side code will run and set the hidden field flag and any other information needed then the update panel animation extender will run the javascript function after the update panel have been updated and will check the hidden field and find it filled with data and will trigger the show dialog and then reset the flag so any other post back will not show the dialog.

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

#3


0  

Try modifying your DOM before opening the dialog

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

In code :

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

In JS :

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

#4


0  

See this

Try adding a call to $('#dialog').dialog('open')

尝试添加对$('#dialog')的调用。对话框('打开')

your first call to $('#dialog').dialog([Parmas]) may be creating it but not opening it.

你第一次调用$('#dialog')。对话框([Parmas])可能正在创建它但不能打开它。

Something like this:

像这样的东西:

 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

#1


3  

I have had a lot of issues with jQuery awesomeness and UpdatePanels. Try this approach:

我在jQuery awesomeness和UpdatePanels方面遇到了很多问题。试试这种方法:

  1. Place the div that you are using for your dialog outside of your update panel. Don't create your dialog in code behind. Instead create your dialog on page load. Since your dialog is outside the updatepanel it won't get clobbered. Make sure to not auto-open it.
  2. 将用于对话框的div放在更新面板之外。不要在后面的代码中创建对话框。而是在页面加载时创建对话框。由于您的对话框在updatepanel之外,因此不会被破坏。确保不要自动打开它。

  3. Add an additional div to your dialog div to hold your content.
  4. 在对话框div中添加一个额外的div来保存您的内容。

  5. Create a javascript function that
    • clears the contents of the content div in your dialog of any previous content
    • 清除对话框中任何先前内容的内容div的内容

    • appends the gvLog control to the dialog content div, something like $('#dialogContent').append($('#<%= gvLog.ClientID %>'));
    • 将gvLog控件附加到对话框内容div,类似于$('#dialogContent')。append($('#<%= gvLog.ClientID%>'));

    • shows the dialog
    • 显示对话框

  6. 创建一个javascript函数,清除对话框中内容div的内容,将gvLog控件附加到对话框内容div,如$('#dialogContent')。append($('#<%= gvLog。 ClientID%>'));显示对话框

  7. Now in your code behind tweak the RegisterClientScriptBlock to call this new javascript function.
  8. 现在在你的代码后面调整RegisterClientScriptBlock来调用这个新的javascript函数。

Example Code
Code Behind:

示例代码背后:

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);
    }
}

Designer Code:

<%@ 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>

#2


0  

There is a very tricky solution for your problem that will save you from all the hassle of the update panel and the jquery.

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

First, we will not depend on the RegisterClientScriptBlock function and instead everything will be done through hidden fields.

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

  1. Create a hidden field that will flag if the show dialog to be show or not.
  2. 创建一个隐藏字段,该字段将标记是否显示show对话框。

  3. Create a javascript function that check if hidden field has value or not. If the hidden field had value, display the show dialog and depend on hidden fields to get the data else don't show the dialog, this will fix the problem of the post back show dialog issue.
  4. 创建一个javascript函数,检查隐藏字段是否有值。如果隐藏字段有值,则显示show对话框并依赖隐藏字段获取数据,否则不显示对话框,这将解决post back show对话框问题。

  5. add an animation extender to the update panel
  6. 将动画扩展器添加到更新面板

<cc1:UpdatePanelAnimationExtender ID="UpdatePanelAnimationExtender1" TargetControlID="UpdatePanel1" runat="server"> <Animations> <OnUpdated> <Parallel duration="0">
<ScriptAction Script="YouFunctionCall();" /> </Parallel> </OnUpdated> </Animations> </cc1:UpdatePanelAnimationExtender>

and at the end of this javascript function clear the hidden field.

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

So what will happen, at post back the javascript will run to check if the flag is set or not and it will find that the flag is empty and when you click inside the update panel, your server side code will run and set the hidden field flag and any other information needed then the update panel animation extender will run the javascript function after the update panel have been updated and will check the hidden field and find it filled with data and will trigger the show dialog and then reset the flag so any other post back will not show the dialog.

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

#3


0  

Try modifying your DOM before opening the dialog

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

In code :

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

In JS :

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

#4


0  

See this

Try adding a call to $('#dialog').dialog('open')

尝试添加对$('#dialog')的调用。对话框('打开')

your first call to $('#dialog').dialog([Parmas]) may be creating it but not opening it.

你第一次调用$('#dialog')。对话框([Parmas])可能正在创建它但不能打开它。

Something like this:

像这样的东西:

 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