views:

61

answers:

3

This is a simplified version of what I want to do. Basically I have a datalist with a bunch of stuff in it and when you mouseover items in the datalist I want jquery to hide/show stuff. The problem is that after I databind my gridview/repeater/datalist jquery quits working if the gridview/repeater/datalist is in an update panel.

After you click the button in the sample below, the jquery that makes the span show up when you mouse over quits working.

Any ideas of why this is happening, how to fix it or a better way to do this?

   <script type="text/javascript">
                $(document).ready(function() {
                    $('.comment-div').mouseenter(function() {
                        jQuery("span[class=mouse-hide]", this).fadeIn(50);
                    });
                    $('.comment-div').mouseleave(function() {
                        jQuery("span[class=mouse-hide]", this).fadeOut(50);
                    });
                });
            </script>

            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                <ContentTemplate>
                    <div class="comment-div">
                        <asp:GridView ID="GridView1" runat="server">
                        </asp:GridView>
                        <span class="mouse-hide" style="display: none;">sdfgsdfgsdfgsdfg</span>
                    </div>
                    <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
                </ContentTemplate>
            </asp:UpdatePanel>

And the code-behind:

 protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            BindStuff();
        }
    }
    public void BindStuff()
    {
        TestDB db = new TestDB();
        var x = from p in db.TestFiles
                select new { p.filename};
        x = x.Take(20);
        GridView1.DataSource = x;
        GridView1.DataBind();
    }
    protected void Button1_Click(object sender, EventArgs e)
    {
        BindStuff();
    }
+2  A: 

When the UpdatePanel refreshes, it completely replaces all of the DOM elements that you had previously attached event handlers to. The easiest fix is to initialize your event handlers in pageLoad() instead of $(document).ready(). Its code will be executed both on the initial page load, but also after every UpdatePanel refresh.

The better solution is to change your code to use live() or delegate(), so that the event handlers aren't impacted by periodic changes in the page's contents.

Dave Ward
+1 - you beat me to it. Also, I was unaware of the pageLoad() quirks. Very cool.
Ryan Kinal
You have to be careful when wiring up events in pageLoad(), whether using jQuery or ASP.NET AJAX's $addHandler, because it's possible to wire up multiple copies of the same event to the same element.
Marko
But you can use $(element).unbind() before assigning each event to make sure it doesn't get added twice.
Marko
Thanks - This is what I will try.
Blankasaurus
+1  A: 

When you do a AJAX postback using an update panel the DOM within it's removed and re-created when the AJAX response arrive. The handlers you attached are lost unless you use the live method or the livequery library

Claudio Redi
+2  A: 

Hi Chris,

The reason this is happening is because the controls get recreated on a partial postback. Use the 'live' feature of jQuery so rewrite your code like:

$(document).ready(function() {
    $('.comment-div').live('mouseenter',function() {
        jQuery("span[class=mouse-hide]", this).fadeIn(50);
    });
    $('.comment-div').live('mouseleave', function() {
        jQuery("span[class=mouse-hide]", this).fadeOut(50);
    });
});
Marko
Thanks for the code snippet. +1
Blankasaurus