views:

288

answers:

4

I am calling a jquery function after inserting a record to database...

ScriptManager.RegisterClientScriptBlock(LbOk, typeof(LinkButton), "json",
                             "topBar('Successfully Inserted');", true);

I have included this in my master page for executing jquery function after a postback,

<script type="text/javascript">
    function load() {
 Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
      }
    function EndRequestHandler()
       {
           topBar(message);
     }


 function topBar(message) {
    alert(a);
    var alert = $('<div id="alert">' + message + '</div>');
    $(document.body).append(alert);
    var $alert = $('#alert');
    if ($alert.length) {
        var alerttimer = window.setTimeout(function() {
            $alert.trigger('click');
        }, 5000);
        $alert.animate({ height: $alert.css('line-height') || '50px' }, 200).click(function() {
            window.clearTimeout(alerttimer);
            $alert.animate({ height: '0' }, 200);
        });
    }
}
    </script>

<body onload="load();">

But it doesn't seem to work... Any suggestion..

+2  A: 

Assuming that your code-behind is running during an UpdatePanel refresh, could there be a bad interaction between your EndRequest handler and your code-behind registration? topBar() should be getting called twice, once with your "Successfully Inserted" message and then once with an undefined parameter in EndRequest (unless the message variable is defined somewhere we can't see here).

Also keep in mind that $('#alert') can return more than one item. If topBar() is being called more than once, that is probably the case.

How about doing something like this, for starters, to mitigate that unintended side effect:

function topBar(message) {
  var $alert = $('<div/>');

  $alert.text(message);

  $alert.click(function () {
    $(this).slideUp(200);
  });

  $(body).append($alert);

  // Doesn't hurt anything to re-slideUp it if it's already
  //  hidden, and that keeps this simple.
  setTimeout(function () { $alert.slideUp(200) }, 5000);
}

That doesn't fix the issue of EndRequest and Register*Script both executing topBar(), but that should keep them from conflicting so you can see what's going on better.

Give that a try and let us know if that changes things.

Dave Ward
@Dave Ward: It worked for the first 2-3 time after that it dint work
bala3569
What happened when it didn't work? Nothing at all? Are you positive that there wasn't a JavaScript error or a server-side error during the async postback (which would've prevented the Register*Script from emitting its payload)?If you use Firebug to set a breakpoint in the topBar() function, is that function being entered at all when it doesn't work right?
Dave Ward
+2  A: 

With Chrome and Firefox, the only issue that I had was the var alert being the same name as the alert() call.

    function topBar(message) {
        alert(message);
        var alertDiv = $('<div id="alert">' + message + '</div>');
        $(document.body).append(alertDiv);
        var $alert = $('#alert');

It's possible that your body tag isn't loaded at the time of the script running, which would mean that the $(document.body) reference would be empty - which jquery would silently fail to add the alert div to. Either way, it never hurts to wrap your calls in a $(document).ready event:

    ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "json",
                         "$(document).ready(function() { topBar('Successfully Inserted');});", true);
mattdekrey
+2  A: 

Here's a full working example:

<%@ Page Title="Home Page" Language="C#" AutoEventWireup="true" %>
<script type="text/C#" runat="server">
    protected void BtnUpdate_Click(object sender, EventArgs e)
    {
        // when the button is clicked invoke the topBar function
        // Notice the HtmlEncode to make sure you are properly escaping strings
        ScriptManager.RegisterStartupScript(
            this, 
            GetType(), 
            "key", 
            string.Format(
                "topBar({0});", 
                Server.HtmlEncode("Successfully Inserted")
            ), 
            true
        );
    }    
</script>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title></title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"&gt;&lt;/script&gt;
    <script type="text/javascript">
        function topBar(message) {
            var alert = $('<div id="alert">' + message + '</div>');
            $(document.body).append(alert);
            var $alert = $('#alert');
            if ($alert.length) {
                var alerttimer = window.setTimeout(function () {
                    $alert.trigger('click');
                }, 5000);
                $alert.animate({ height: $alert.css('line-height') || '50px' }, 200).click(function () {
                    window.clearTimeout(alerttimer);
                    $alert.animate({ height: '0' }, 200);
                });
            }
        }
    </script>
</head>
<body>
    <form id="Form1" runat="server">

    <asp:ScriptManager ID="scm" runat="server" />

    <asp:UpdatePanel ID="up" runat="server">
        <ContentTemplate>
            <!-- 
                 You could have some other server side controls 
                 that get updated here 
            -->
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger 
                ControlID="BtnUpdate" 
                EventName="Click" 
            />
        </Triggers>
    </asp:UpdatePanel>

    <asp:LinkButton 
        ID="BtnUpdate" 
        runat="server" 
        Text="Update" 
        OnClick="BtnUpdate_Click" 
    />

    </form>
</body>
</html>
Darin Dimitrov
+2  A: 

This doesn't answer your question directly, but is more meant to pass on another technique to call page methods without using update panels, but directly from jQuery.

Just decorate your page method (in the partial class of the codebehind) like so (it must be static):

[WebMethod]
[ScriptMethod(ResponseFormat=ResponseFormat.Json, XmlSerializeString=true)]
public static bool UpdateDatabase(string param1 , string param2)
{
    // perform the database logic here...

    return true;
}

Then, you can call this page method right from jQuery's $.ajax method:

$("#somebutton").click(function() {

  $.ajax({
    type: "POST",
    url: "PageName.aspx/UpdateDatabase",
    data: "{ param1: 'somevalue', param2: 'somevalue' }",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data) {
      if (data.d) {
        topBar("success!");
      } else {
        topBar("fail");
      }
    }
  });

});

It's very simple, and a lot cleaner that trying to register scripts. No need to create a web service either.

This is a great article:

http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/

ScottE