Geekpedia Programming Tutorials






ASP.NET 2.0 Script CallBack (Ajax like)

Learn about the new ASP.NET 2.0 feature which allows you to do CallBack (similar to PostBack) on a form without reloading the page. This technique similar to Ajax uses the ICallbackEventHandler interface.

On Friday, December 23rd 2005 at 02:58 PM
By Andrei Pociu (View Profile)
****-   (Rated 4.1 with 256 votes)
Contextual Ads
More ASP.NET Resources
Advertisement
Download this Visual Studio 2005 project Download this ASP.NET 2.0.50215 (BETA) C# project (can easily be converted to VB.NET)



Download this Visual Studio 2005 project Download this ASP.NET 2.0.50727 C# project (can easily be converted to VB.NET)



You probably already know what Ajax does, or maybe not, but what's certain is that you heard about Ajax because much fuss is created around it on the web.

In this tutorial you're going to learn a very interesting technique of combining client-side JavaScript with server-side ASP.NET 2.0. More exactly, we're going to implement a simple rating system (a listbox and a button) which can be used to rate content on websites. But there's something special about it: when the visitor clicks the button to submit the rating, the page will not reload, but the rating will be quietly sent to the server. From the server-side you can then do whatever you want with that value. You're probably going to put it in a database. After the server finished adding the rating to the database, a client-side event will fire which you can use to notify the visitor with a message on the page "Content rated successfully!". But once again without any page refresh. Everything works like in a Windows forms application.



Script Callback Example



This can be accomplished with Ajax, but we're not going to use Ajax in this tutorial. We're going to use a new technique implemented in ASP.NET 2.0 (you'll have to find an alternative if you're using ASP.NET 1.1): ICallbackEventHandler. This technique is very simple, and very appropriate for what we are trying to do. There are multiple examples on the web that accomplish a similar objective to the one in this tutorial, but the code is messier. This code is tested and works without problems in Internet Explorer and Firefox, so the major browsers are covered.



First, let's place the HTML tags we're going to use:






<p>Please click to rate (no refresh):</p>
<select runat="server" id="selRate">
   <option value="Poor">Poor</option>
   <option value="Mediocre">Mediocre</option>
   <option value="Fair" selected="selected">Fair</option>
   <option value="Good">Good</option>
   <option value="Excellent">Excellent</option>
</select>
<input type="button" runat="server" id="btnRate" value="Rate" />
<br /><br />
<div id="Result"></div>




As you can see above, we have a listbox from where the visitor can choose a rating. Then the btnRate button is pressed, but there is no onclick attribute because we will set the onClick attribute from server side.

Below we have the Result div, which will be used for displaying the result of adding the vote. The message inside the Result div will be set using server-side code.



Now let's move to the C# code-behind. First modify the class declaration of the page to include the ICallbackEventHandler interface, like in the example below:





public partial class _Default : System.Web.UI.Page, ICallbackEventHandler;



Moving on, add the following two lines in the Page_Load event:





string CallbackRef = Page.ClientScript.GetCallbackEventReference(this, "document.getElementById('selRate').value", "RateContent", "null");

btnRate.Attributes["onclick"] = String.Format("javascript:{0}", CallbackRef);



What's important for you to understand from these two lines is that on the first line a Javascript function is actually created and stored in a string.

The parameters passed to GetCallbackEventReference() which should concern you are document.getElementById('selRate').value which is the value we want to retrieve from the client side (the value of the selected value in the listbox which is the actual rating) and RateContent which is the name of the JavaScript event that's going to be called back on the client side when the server side finished its job.

The second line adds the onclick attribute we talked about earlier, to the btnRate button, with a call to the function that's stored inside CallbackRef. So basically we're creating some JavaScript code from the server-side, so that when the button is clicked, the function stored inside CallbackRef is called.



We're done with the code in the Page_Load event. Now we have one more thing to do in the server-side code: a virtual method
named RaiseCallbackEvent where you can do your server-side coding, such as adding the vote to the database. Here's how the method looks like:





public virtual string RaiseCallbackEvent(string eventArgument)

{

   // Here we will store the result of adding the vote, which will be passed to the client side code

   string VoteResult;


   // TODO HERE: Add the vote to the database or your option of storing data


   // We'll pretend the vote was added to the database and everything was successful

   VoteResult = "Your vote of <i>" + eventArgument + "</i> was registered successfully!";


   return VoteResult;

}




Now I have to confess something: the above method - RaiseCallbackEvent(string eventArgument)- only works in ASP.NET 2.0.50215 (.NET Framework Beta). If you try to use it in the final version of ASP.NET (2.0.50727), you will get an error similar to the following: '_Default' does not implement interface member 'System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string)'.



The reason for that you can find in a topic at the MSDN forums. So if you're running the final version of ASP.NET 2.0, you'll have to use the following longer piece of code instead:





private string _callbackArg;


void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)

{

   _callbackArg = eventArgument;

}


string ICallbackEventHandler.GetCallbackResult()

{

   return RaiseCallbackEvent(_callbackArg);

}



protected virtual string
RaiseCallbackEvent(string eventArgument)

{

   // Here we will store the result of adding the vote, which will be passed to the client side code

   string VoteResult;


   // TODO HERE: Add the vote to the database or your option of storing data


   // We'll pretend the vote was added to the database and everything was successful

   VoteResult = "Your vote of <i>" + eventArgument + "</i> was registered successfully!";


   return VoteResult;

}




As you probably figured out, the eventArgument argument contains the value originally pased by the client-side, which in our case is the value of the selected listbox item. I'm not going to provide source code on how to add the vote in the database on this tutorial since it would be out of its original scope. But we'll pretend we did and set the VoteResult string to a message shouting success.



We're almost done, but there's one more step: the JavaScript function which is going to update the page saying the vote was added successfully. So back to client-side, add the following script:





<script type="text/javascript">
   function RateContent(result, context)
   {
      document.getElementById('Result').innerHTML = result;
   }
</script>



Remember the RateContent attribute which we passed to GetCallbackEventReference method back in the server-side C# code and we said it's the name of the JavaScript event which is going to be called on the client-side? Well this is it - this is the function that's called after the server-side has completed the work. And as you can see, in this function we simply set the content of a div with the success message returned by the server-side code.



This is all you need to do to accomplish the wonderful functionality of submitting a form, or in our case adding a vote to a database, without refreshing the page. Most of the visitors hate when the page refreshes or a popup shows just for the simple task of rating an article, therefore this kind of functionality will be welcomed on your website. And thanks to ASP.NET 2.0 it can be accomplished quite easily.
Digg Digg It!     Del.icio.us Del.icio.us     Reddit Reddit     StumbleUpon StumbleIt     Newsvine Newsvine     Furl Furl     BlinkList BlinkList

Rate Rate this tutorial
Comment Current Comments
by Padschild on Friday, January 20th 2006 at 08:44 AM

Hey,

Good tutorial, works for me.. but one question,

How can I do this with let's say.. 2 or more controls (buttons.. or whatever..) at 1 html page? How does the callback knows which control it was?

Thanks!

Padschild

by Andrei Pociu on Friday, January 20th 2006 at 12:19 PM

You need to change the code-behind to pass the button name instead of the drop-down list value. For each button you have, you will use the following two lines:

string callbackRef = Page.ClientScript.GetCallbackEventReference(this, "myFirstButton", "FavorHeadline", "null");

myFirstButton.Attributes["onclick"] = String.Format("javascript:{0}", callbackRef);

You will also need to change the JavaScript to pass the name of the button (or whatever value you want that helps you figure which button was pressed).
Inside RaiseCallbackEvent() you will find this value (the name of the button or whatever value you passed) in the <i>eventArgument</i> variable.

I did this for a website (Feedpedia.com) and it works great.
But if I find an easier solution, I will post it here.

by Anand Ganesh on Wednesday, January 25th 2006 at 07:32 PM

Hi Thanks for the info. It works well.

I have a question.

The sample shows the event argument as type "string" can I pass a class as an argument?

Thanks
Anand Ganesh

by Ivelina on Thursday, February 16th 2006 at 08:06 AM

Hi,
how can I make callback using a timer, and not button event?

by Neil on Thursday, March 9th 2006 at 10:36 AM

Ivelina,

To use a timer event rather than a button, add a tag and then use the settimeout function to simulate the onclick event

e.g.
have a control in your page like this:
<a href="" id="timer" runat="server"></a>

then on your onload event of the body tag, have a count function, e.g.

function count()
{
document.getElementById('timer').onclick();
window.setTimeout("count()",1000);
}

This should achieve what you want

by Curt on Thursday, March 16th 2006 at 11:54 AM

Great tutorial. How do I do this from within a content page that is a child of a master page???? I can\\\'t get it to work. If I do this in a form alone...no problem. Thanks!!!!

by Reena on Tuesday, March 28th 2006 at 04:43 PM

<p>Curt,</p>
<p>Does work with Master pages. Code in VB...</p>
<p>ASPX file...</p>
<p>&lt;asp:Content ID=&quot;Content1&quot; ContentPlaceHolderID=&quot;cntTestMain&quot; Runat=&quot;Server&quot;&gt;<br />
</p>
<p> &lt;div&gt;<br />
&lt;p&gt;Please click to rate (no refresh):&lt;/p&gt;<br />
&lt;select runat=&quot;server&quot; id=&quot;selRate&quot;&gt;<br />
&lt;option value=&quot;Poor&quot;&gt;Poor&lt;/option&gt;<br />
&lt;option value=&quot;Mediocre&quot;&gt;Mediocre&lt;/option&gt;<br />
&lt;option value=&quot;Fair&quot; selected=&quot;selected&quot;&gt;Fair&lt;/option&gt;<br />
&lt;option value=&quot;Good&quot;&gt;Good&lt;/option&gt;<br />
&lt;option value=&quot;Excellent&quot;&gt;Excellent&lt;/option&gt;<br />
&lt;/select&gt;<br />
&lt;input type=&quot;button&quot; runat=&quot;server&quot; id=&quot;btnRate&quot; value=&quot;Rate&quot; /&gt;<br />
&lt;br /&gt;&lt;br /&gt;<br />
&lt;div id=&quot;Result&quot;&gt;<br />
&lt;asp:Label ID=&quot;lblResult&quot; runat=&quot;server&quot; Text=&quot;Label&quot;&gt;&lt;/asp:Label&gt;&lt;/div&gt;<br />
&lt;/div&gt;<br />
<br />
&lt;script type=&quot;text/javascript&quot;&gt;<br />
function RateContent(result, context)<br />
{<br />
document.getElementById(&quot;&lt;%= strMasterID %&gt;&quot; + 'lblResult').innerHTML = &quot;test&quot;;<br />
}<br />
&lt;/script&gt;<br />
&lt;/asp:Content&gt;</p>
<p>-----------------<br />
ASPX.VB</p>
<p>Partial Class Test_Callback<br />
Inherits System.Web.UI.Page<br />
Implements ICallbackEventHandler</p>
<p> Public Shared strMasterID As String</p>
<p> Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init<br />
strMasterID = Me.Master.ClientID &amp; &quot;_cntTestMain_&quot;<br />
End Sub</p>
<p> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load</p>
<p> Dim CallbackRef As String = Page.ClientScript.GetCallbackEventReference(Me, &quot;document.getElementById('&quot; &amp; strMasterID &amp; &quot;selRate').value&quot;, &quot;RateContent&quot;, &quot;null&quot;)</p>
<p> btnRate.Attributes(&quot;onclick&quot;) = String.Format(&quot;javascript:{0}&quot;, CallbackRef)<br />
End Sub</p>
<p> Private _callbackArg As String</p>
<p> Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent</p>
<p> _callbackArg = &quot;Your vote of &lt;i&gt;&quot; &amp; eventArgument &amp; &quot;&lt;/i&gt; was registered successfully!&quot;</p>
<p> End Sub<br />
</p>
<p> Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult<br />
Return _callbackArg<br />
End Function<br />
</p>
<p>End Class<br />
</p>

by Winnie on Friday, April 28th 2006 at 11:44 AM

Hi. I've been trying to make it work for my sample project. I'm using a master page file with a contentplaceholder to display my results page on the right side of my form. My left side is navigated by a treeview control that has a source ID tied to a SiteMapDataSource. The Map.Sitemap is just a bunch of page links that I'l like the user to left once displayed on the treeview. They get to click on any tree node on the left and display the resulting page on the content side. As you expect, the page keeps reloading everytime for every click and page load. I 'm trying to use your example but can't seem to get it to work. Can you please show me how in VB.NET? Tks

by Rups on Sunday, July 9th 2006 at 10:48 PM

Great tutorial. It's really very helpfull. Heartly thanks to all.

Regards,
Rups

by Steve on Wednesday, August 9th 2006 at 11:51 AM

Winnie, I've the same problem. The webform_docallback doesn't seem to return to the content page but also does not perform an exception or report any error, it just does nothing. I have a feeling it fails because the code doesn't know where to send the callback and just does nothing instead.

by Rodzilla on Monday, August 14th 2006 at 05:09 PM

Steve - pls check if you have implemented the same javascript function name that you pass in the Page_Load event (RateContent in the above tutorial). If so, then pls place a break point in the \'public virtual string RaiseCallbackEvent\' and make sure that the code reaches it successfully.

Hope this helps,
Rodz

by sina Tikab on Friday, December 8th 2006 at 02:15 PM

Nice code =)

by mahalakshmisethu on Thursday, December 14th 2006 at 04:59 AM

hi,
Excellent tutorial. but i want insert some string with that comment textbox value
here that code,

GetCallbackEventReference(this, ("document.getElementById(\'" + (strMasterID + "Comment_TextBox\').value")), "CommentContent", "null") can you help me.

Thanks & Regards
MahalakshmiSethu

by mahalakshmisethu on Thursday, December 14th 2006 at 05:22 AM

hi,
i get result from database and i want to display my result into datagrid control.can we do that one. can you please help me.


Thanks & Regards,
MahalakshmiSethu

by mahalakshmisethu on Thursday, December 14th 2006 at 06:50 AM

hi,
i get result from database and i want to display my result into datagrid control.can we do that one. can you please help me.


Thanks & Regards,
MahalakshmiSethu

by suresh on Tuesday, May 29th 2007 at 05:35 AM

Hi,
I get result from database and i need to display the result into gridview, Can you please help me.

Thanks&Regards
Suresh.

by Atanu on Thursday, June 21st 2007 at 09:31 AM

My program works good with the example.

But after showing the data it make a round trip
How to block that

by ddd on Tuesday, October 30th 2007 at 01:07 AM

heloooooooooooooooo

by prashant on Monday, December 17th 2007 at 12:33 AM

hi,
its great....
if it is not ajax.
then in ajax how we perform this..

by dazy on Tuesday, January 22nd 2008 at 06:11 PM

Very good tutorials, thanx.

by on Saturday, February 16th 2008 at 01:57 AM

1

by John on Friday, April 18th 2008 at 12:55 PM

How could this be implemented if several labels need to be updated based on a selected item in a drop-down list?

by Santosh on Wednesday, May 21st 2008 at 02:01 AM

hi i have 2 text boxes instead of dropdownlist
on button click insert data into datbase but how can i do in RaiseCallbackEvent

by abc on Wednesday, June 18th 2008 at 12:28 AM

adding comment

by adil on Friday, June 20th 2008 at 06:53 AM

not working with vs2005

by yaser on Wednesday, July 23rd 2008 at 08:43 AM

i want to CallServer() in MasterPage how can i do it? any help...

following is i am doing in MasterPage.cs but the call server function is not working please help.


private void RegisterClientCallbacks()
{
Page manger1 = new Page();
string callbackRef = manger1.ClientScript.GetCallbackEventReference(this, "arg", "RecieveServerData", "context");
string script = String.Empty;
if (!manger1.ClientScript.IsClientScriptBlockRegistered("CallServer"))
{
script = "function CallServer(arg,context) { " callbackRef "}";
manger1.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", script, true);
}
}


Comment Comment on this tutorial
Name: Email:
Message:
Comment Related Tutorials
There are no related tutorials.

Comment Related Source Code
There is no related source code.

Jobs ASP.NET Job Search
My skills include:
Enter a City:

Select a State:


Advanced Search >>
Latest Tech Bargains

Advertisement

Free Magazine Subscriptions

Today's Pictures

Today's Video

Other Resources

Latest Download

Latest Icons