Calling a jquery function from code behind in asp.net doesn't seem to work

10,700

Solution 1

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">
<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"></script>
    <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>

Solution 2

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/

Solution 3

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.

Solution 4

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);
Share:
10,700
bala3569
Author by

bala3569

Interested in software development, primary on the .NET Framework1 Email: [email protected]

Updated on July 19, 2022

Comments

  • bala3569
    bala3569 almost 2 years

    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..

  • rlorenzo
    rlorenzo almost 14 years
    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?
  • Brian Webster
    Brian Webster over 12 years
    Confirmed working. My code calls UnFreezeScreen(). ScriptManager.RegisterStartupScript(BTN_Submit, BTN_Submit.GetType(), "key", "UnFreezeScreen();", True)
  • hsobhy
    hsobhy about 10 years
    Thanks for that solution but if I can know how can I get this to work with multiple actions and using messages cases sent from code behind? iff you got time kindly update or jsFiddle a small example..thanks