Nikolaos Kantzelis ASP.Net Blog

This blog will focus on ASP.NET Framework

Sponsors

About Me

Great Blogs

September 2011 - Posts

Creating custom error pages in ASP.Net applications

This is going to be another short post regarding ASP.Net and custom error pages. Our goal is to specify a particular page to be displayed on the user's screen when error occurs within our application.In order to that we basically have to make some changes in the web.config file.

1) Launch Visual Studio and create a new ASP.Net web application from the available projects. 

2) Let's create the generic error page. Add another item to your project , an .htm page. I have named it GenericError.htm

Add some markup on the page

 <h2>There has been an error....</h2>
    <p>There was a problem processing your request.
    you can try later or contact support
    <a href="http://www.thesupport.com"</a>
  </p>

3) Let's create another custom error page for files not found on the server. Add another item to your project , an .htm page. I have named it notfound.htm

I have added some simple markup 

<p>We are sorry but the page you requested is not found in our server!!!!</p>

4) Now let's make the necessary adjustments to the web.config file.We have to add a customErrors element.

 <customErrors defaultRedirect="GenericError.htm" mode="On">
          <error statusCode="404" redirect="notfound.htm"/>
      </customErrors>

We have  various options we can set to the mode attribute. We can set it to On which means that the custom error pages will be always displayed.

Then there is the Off option which means we always display to everyone ASP.Net error pages. That is not the best option...It reveals far too much information about the error to people who may have the knowledge to harm our application.The third option and the one I use is RemoteOnly which means that ASP.Net error pages will be shown only when I am on the web server and hit an error and custom error pages will be shown to the remote clients.

5) Add another page to your application, a web form. Name it Exception.aspx

Add a button on your web page and leave the default name. In the Click() event handling routine type

        protected void Button1_Click(object sender, EventArgs e)
        {
             throw new ApplicationException("I am an exception!");
        }

 

6) Run your application and hit the button to generate an exception/error. You will see the contents of the GenericError.htm

If you type in the address bar  http://localhost:33173/Exceptionnnnnn.aspx instead of http://localhost:33173/Exception.aspx you will see the contents of the notfound.htm

7) Now let's change the web.config a bit.
 <customErrors defaultRedirect="GenericError.htm" mode="Off">
          <error statusCode="404" redirect="notfound.htm"/>
      </customErrors>
Run your application and hit the button to generate an exception/error. You will not see the contents of the GenericError.htm  but the ASP.Net error page.

8) Now let's change the web.config a bit.
 <customErrors defaultRedirect="GenericError.htm" mode="RemoteOnly">
          <error statusCode="404" redirect="notfound.htm"/>
      </customErrors>

Run your application and hit the button to generate an exception/error. You will not see the contents of the GenericError.htm  but the ASP.Net error page.

When I upload the page on a remote web server and try to access the page as a remote client, I will see the contents of the GenericError.htm  and not the ASP.Net error page.

This is the best setting(mode="RemoteOnly") in my mind  for someone to set.

Hope it helps!!!

Take an ASP.Net application offline

In this post (it is going to be very short for a change) I would like to show you how to take your ASP.Net application offline.

We have to place a file named app_offline.htm into your root directory.By doing that we stop any ASP.Net processing. If you wonder what is going to be displayed instead,

are the contents of the  app_offline.htm. If we remove the app_offline.htm  or rename it, then the ASP.Net application will start again.

1) Launch Visual Studio and create a new ASP.Net web application.Give it an appropriate name.

2) Add a new app_offline.htm file to the root of your application. I have added some markup in this file

<p>We apologise for the inconvenience but our site is down for maintenance!!!
 We  expect this to last for a couple more hours. Please try again later </p>
<p>If you want to have a look at our company's profile have a 
look at some <a href="#">videos</a> in YouTube</p> 

3) Run your application and you will see the contents of the app_offline.htm file

4)  Rename the app_offline.htm file to something else and you will see your application up and running. You can delete the file if you want.

So  I think this is a great way to take your application off and bring it back on with minimum effort.

Hope it helps!!!

An introduction to ASP.Net health monitoring and web events

In this post I would to focus on ASP.Net Health monitoring and Web events.Health monitoring is another mechanism to capture/abstract logging.

In most cases with our ASP.Net applications we need to trace what happens when they are up and running. Have a look at a previous post of mine where I talk about Tracing at page and application level.

In this post I would like to talk about Web events.

The web event represents the data that is to be logged.We can raise those events and those events can be logged by various providers like email,SQL Server,EventLog.

Some of the most common events are WebAuditEvent that logs every time someone logs in successfully or unsuccessfully through forms authentication.

Another web event is WebBaseErrorEvent that logs any sort of unhandled exception.It is the base class for all the health-monitoring error events.

All these events are logged to the Event Log.Logging is turned on by default.

Have a look here to find more about ASP.Net health monitoring and web events.

I am going to demonstrate the various aspects of Health Monitoring with hands on demos.

1) Launch Visual Studio and create a new ASP.Net application. Choose C# as the development language.

2) Add a new page to your application. Name it Exception.aspx

3) Add a button on your web page and leave the default name. In the Click() event handling routine type

protected void Button1_Click(object sender, EventArgs e)
        {
          throw new ApplicationException("I am an exception!");
        }

4) When you run the page and click the button an exception is generated and you get back an ASP.Net error page with the exception details and the source error.

If you go and view the Event Log through the Event Viewer (Just type Event Viewer in the Run window in Windows)

Have a look at the picture below

 

 So we have lots of information we can look into regarding this exception. We can look at the stack trace, the user information, the exception information.

 5) To recap, exceptions and failed security audit messages sent to the EventLog provider.We can change that and log them to an SQL Server database. In order to do that we must create a database first and make changes to the web.config file.

I added this element in my web.config file.

  <healthMonitoring enabled="true" heartbeatInterval="10">
    <rules>
 
 <add name="TheRule" eventName="Heartbeats" provider="SqlWebEventProvider"/>
<add name="TheSecondRule" eventName="All Errors" 
provider="SqlWebEventProvider"/>

 
   </rules>
      </healthMonitoring>

 We have added a rule that maps a range of events to a provider.In our case to the SqlWebEventProvider.

 6) Now I need to setup the database.Ιn the web.config file I have to make some changes to the connectionStrings element to define the path and the

 <connectionStrings>
    <clear/>
  <add name="LocalSqlServer"
   connectionString="data source=.\SQLEXPRESS;database=aspnetdb;
   Integrated Security=SSPI" />
  </connectionStrings>

 Then obviously we need to generate this database.

Go to Start->All Programs-> Visual Studio->Visual Studio Command prompt and type aspnet_regsql. Then the wizzard pops up and by following the steps of the wizzard you will create the provider database.

Now if you go and refresh the databases list in the Object Explorer in SSMS you will see the new database created. Now I need to grant permissions to my web application to be able to write to it.My account name that I run the application under is  fofo-PC\fofo. This is the machine's administrator password and it is also an account (login) that belongs to the sysadmin fixed server role.So I do not need to do anything more in order to have write access to the database.

 7) View the Exception.aspx page in the browser once more and click the button to generate an exception. Obviously an exception will be genereated. Select the table (aspnet_WebEvent_Events) from your database, and do a (Select * from aspnet_WebEvent_Events). Have a look at the results. The HeartBeat events and the other errors are all in there.

The exception now will be both logged in the Event Log and the database.

Have a look at the picture below to see what I see when I get results back from the aspnet_WebEvent_Events table.

 

8)  Now we can add a rule that will map to email.In order to email we need to setup a provider and add a third rule so the we receive information (errors/exceptions) through the email.

Ηave a look at the changes in the 

      <healthMonitoring enabled="true" heartbeatInterval="10">
          <rules>
 
<add name="TheRule" eventName="Heartbeats" provider="SqlWebEventProvider"/>
<add name="TheSecondRule" eventName="All Errors" provider="SqlWebEventProvider"/>
<add name="TheEmailRule" eventName="All Errors" provider="EmailProvider"/>
        
     </rules>
          <providers>
              <add name="EmailProvider"
           type="System.Web.Management.SimpleMailWebEventProvider,
System.Web,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
            from="admin@mysite.com"
            to="errors@mysite.com"
            buffer="false"
             />
              
              
          </providers>
      </healthMonitoring>

We also have to specify a smtp server. I am going to specify one in my web.config file.Obvioysly I am cheating a bit in this case.I am doing that so I can go on with my example.

In your case you will have to set up the smtp server with the actual settings provided to you by the system administrator.

  <system.net>
        <mailSettings>
 
      <smtp deliveryMethod="SpecifiedPickupDirectory" >
 
   <specifiedPickupDirectory pickupDirectoryLocation="c:\events\email" />
                
      </smtp>
            
        </mailSettings>
    </system.net>

9) Run the page again and click the button to generate an exception. Open the email item from the "C:\events\email" folder. Have a look at its contents. All the information is there.

Have a look at the picture below.

 

 

That is all folks!!!! Hope you found it interesting and learnt how to log events (Adding rules that map a range of events to a provider ) to the Event Log, email and the database.

Hope it helps!!!!

Using JQuery Ajax functions to retrieve data from the server

In this post I would like to talk about the great support that JQuery has for Ajax.I have already written another post on my blog regarding the Jquery Ajax functions and how we can get data form the server.In that post we looked into how we can use the load() method to get data from the server.One of the things you must keep in mind is that JQuery is able to communicate with any server that uses standard protocols.In this post I would like to talk about the get(),post() and ajax() methods and how we can use those methods to get data back from the server through a web service that is hosted there.

The load() function provides us with a very easy way to get HTML data from the server into our application but sometimes we need to be more flexible.By flexible I mean to get JSON , XML data from the server.We can get this type of data from the server using the get() and post() methods.


1) Launch Visual Studio 2010. I am using the ultimate edition but the express edition will do just fine. Create an ASP.Net web application and choose C# as the development language.Give your application an appropriate name

2) We will show how to get html data from the server using the get() method as we did in my other post using the load() method. Add another item to your application, an html page. Name it LoadHtmlFromServerGet.html .  This is going to be a very simple page

<body>
<h1>Load HTML Content from the Server using JQuery</h1>
<br />
<button id="niceButton">
Click here to load HTML from the Server using the Get method!!!!
</button>
<div id="maindiv"></div>
 
 
</body>

 

3) Add another item to your project, an html page. I have named mine jqueryintro.htm.The html markup for my html page is following

 

<body>
<div>jQuery is a fast and concise JavaScript Library that 
simplifies HTML document traversing,event handling, animating,
and Ajax interactions for rapid web development. <strong>
jQuery is designed to change the way that you write JavaScript.</strong>
</div>
 
<div id="new">
 
 
<p><h3>Download jQuery</h3>
 
This is the recommended version of jQuery to use for your application. The code in
here should be stable and usable in all modern browsers. </p>
</div>
 
</body> 

4) I want to load the contents of the jqueryintro.htm in the "maindiv" ID, when the user clicks the button.I will do that by using the get() JQuery Ajax function.We will use this function to make a request to the server.

5) We have to add the following javascript/jquery code to the head section of the LoadHtmlFromServerGet.html

 <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    
   <script type="text/javascript">
        $(document).ready(function () {
            $('#niceButton').click(function () {
                $.get('jqueryintro.htm'function (data) {
                    $('#maindiv').html(data);
                });
            });
        });
 </script>

This is very similar with the load() method.As you can see the get method does not operate on a wrapped set from a selector.It cannot directly update the matched set.

It uses a callback function to do that.

View the page on the browser and click the button to get the data from the server.

8) Now let's have a look on how you can access and get data from a web service.Add a new html page to your application,Loadfromwebservice.htm.

I will pass some parameters/data from this html page to a web service method and get results back.

The markup for this page

<body>
 
	<div id="livfootballers">
		
        <a href="#">kenny</a>
        <a href="#">steven</a>
	
	</div>
 
    <div id="results"></div>
 
</body>

 

 Add a folder in your project. Name it "thefootballers". Inside there i have place two .htm files. I have called the first one kenny.htm and the second one steven.htm.

 The content inside this pages is simple html

 kenny.htm

<body>
<p>
Kenneth Mathieson "Kenny" Dalglish.....
 
</p>
</body>
steven.htm 
 <body>
<p>
Steven Gerrard is.....
 
</p>
</body>
 

The web service method when invoked from the client will get the data from the .htm files and incorporate in the calling html page. 

9) Add a new item on your application , a web service. Name it AjaxJquery.asmx

 Make sure you uncomment this line of code.

   [System.Web.Script.Services.ScriptService]

 I am going to have to create a new method that takes some data from the client page and then sends back data from the relevant .htm page that resides on the server.

 The code for the method follows

        [WebMethod]
        public string FootBallerData()
        {
            string thefootballer = this.Context.Request["footballer"];
            if (thefootballer == ""return string.Empty;
 
 string file = Server.MapPath("~/thefootballers/" + thefootballer + ".htm");
            StreamReader sr = File.OpenText(file);
            string contents = sr.ReadToEnd();
            return contents;
        }

I am storing the data I got from the client side in a variable and then find the .htm file based on that parameter and finally I load the contents of that file in a variable.

10) Now we have to write some javascript code in our Loadfromwebservice.htm page.

I will use the get and post utility methods to send data to the appropriate service method. Inside the <head> section of the page,

I type the following:


    <script src="Scripts/jquery-1.5.js" type="text/javascript"></script>
    <script type="text/javascript">
        // get method
    $(function () {
      $('#livfootballers a').click(function (e) {
         $.get(
	'AjaxJquery.asmx/FootBallerData',
	{ footballer: $(this).text() },
 
	function (response) {
	$('#results').html($(response).text());
		}
	);
                return false;
            });
        });
 
        // post method
        $(function () {
            $('#livfootballers a').click(function (e) {
                $.post(
		'AjaxJquery.asmx/FootBallerData',
	'footballer=' + $(this).text(),
	function (response) {
	$('#results').html($(response).text());
		}
	);
                return false;
            });
        });
</script>

Both methods work equally well.you can comment out one if you want and just use the other one.

11) View the page on the browser and click the links. By doing that you pass the web service that is hosted on the server a parameter (kenny or steven).Then we take the response back from the service and by using the html() method we attach the returned html content to the div with ID results.

12) Let's see now how we can get different type of data from the server and not just html. We can get back JSON data and incorporate it to our html page.

Add a new item in your application , a class file. Name it Footballer.cs

public class Footballer
{
    public int ID { getset; }
    public string FirstName { getset; }
    public string LastName { getset; }
}

 Add a new item in your project , a web form. Name it Footballers.aspx.

The code inside the Footballers.aspx.cs file follows

 

public partial class Footballers : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.ContentType = "application/json";
            var footballer = new Footballer
            {
                ID = int.Parse(Request["id"]),
                FirstName = "Kenny",
                LastName = "Dalglish"
            };
            var serial = new DataContractJsonSerializer(typeof(Footballer));
            serial.WriteObject(Response.OutputStream, footballer);
        }
    }

In the Page_Load event handling routine we construct in memory an object of type Footballer.Then I serialize the object to JSON data. For the folks that do not know what JSON is and why we use it to exchange data among systems have a look here.

Now we need to create another html page. We add a new page to our application and I will name it GetJSON.html

The markup for the page is very easy

 

<body>
 
<button id="JsonButton">Click here to get Json</button>
<div id="results"></div>
 
 
</body>

 Inside the <head> section of the GetJSON.html,  I will write the following javascript code. I am using the getJSON method.

 

    <script type="text/javascript">
    $(document).ready(function () {
      $('#JsonButton').click(function () {
          $.getJSON('Footballers.aspx', { id: 2 },
           function (data) {
              alert('ID: ' + data.ID + ' ' +
              data.FirstName + ' ' + data.LastName);
           });
       });
    });
    </script>

View the page in the browser and click the button. You will pass the ID (id =2) from the client to the server and back to the client. You have placed in the alert box a JSON object.

13) Now I would like to move one and create a simple example using the ajax() method.We can use this method if we want to have full control over making Ajax calls to the server.

Add another web form to your application, name it GetFootballteams.aspx

We will use the ajax() method to get the data from a web service and bring it back to the client.

 The markup follows

<head>
<title>Football Teams</title>
	
<script src="Scripts/jquery-1.5.js" type="text/javascript"></script>
<style type="text/css">
#result { displaynone; }
</style>
<script type="text/javascript">
$(function () {
$('#buttonTeam').click(function () {
    $.ajax({
	   type: "POST",
	   url: "FootballService.asmx/GetTeams",
	   data: "{}",
           contentType: "application/json; charset=utf-8",
	   dataType: "json",
	   success: function (response) {
	   $('#result').html('')
	.append('<p>Here are the teams:</p><ul id="teamsList">');
 
	var teams = response.d;
	for (var i = 0; i < teams.length; i++) {
	$('#teamsList').append('<li>'
		+ teams[i].Name + ' football club, resides on '
		+ teams[i].City + ' and was established on, '
		+ teams[i].Created
		+ '</li>');
	                    }
	                    $('#result').css('display''block');
	                }
	            });
	        });
	    });
 
	
	</script>
</head>
<body>
	<h1>Football Teams</h1>
	<button type="button" id="buttonTeam">Get Teams</button>
	<div id="result"></div>
</body>

Let me explain what I am doing here.I wire up the click even to the button.

$('#buttonTeam').click(function () { ....

Then I call the GetTeams method from the service.I am going to use a POST call to the server.The content that it sends back is JSON.

 Then I append some text to the div result.

success: function (response) {
	   $('#result').html('')
	.append('<p>Here are the teams:</p><ul id="teamsList">'); ..........

 

Then I loop through this set of teams by using the response.d property. Then I append each item and their respective properties in the teamList item I created above.

 var teams = response.d;
	for (var i = 0; i < teams.length; i++) {
	$('#teamsList').append('<li>'
	+ teams[i].Name + ' football club, resides on '
	+ teams[i].City + ' and was established on, '
	+ teams[i].Created
	+ '</li>');
	}

 I am sure you can see how much more power and flexibility we have with the ajax() method.

 

Now we must create the web service.

14) Add another item to your project, a web service. Name it FootballService.asmx

 Make sure you uncomment this line of code.

   [System.Web.Script.Services.ScriptService]

The code inside is

 public class FootballTeam
        {
     public string Name { getset; }
     public string City { getset; }
     public short Created { getset; }
        }
 
List<FootballTeam> FootballTeams = new List<FootballTeam>
{
new FootballTeam{Name = "Liverpool", City = "Liverpool", Created = 1892},
new FootballTeam{Name = "Everton", City = "Liverpool", Created = 1878},
new FootballTeam{Name = "Man Utd", City = "Manchester", Created = 1878},
new FootballTeam{Name = "Arsenal", City = "London", Created = 1886},
new FootballTeam{Name = "Tottenham", City = "London", Created = 1882}
};
 
        [WebMethod]
        public List<FootballTeam> GetTeams()
        {
            return FootballTeams;
        }
    }

 

It is very easy to understand what I am doing in the web service. I have a method GetTeams that return a generic .Net list object, FootballTeams to the client .Before that I create a FootballTeam class and then instantiate a list object FootballTeams.

View the page in the browser and click the button. You will get all the JSON data back from the service.

Have a look the the picture below and see the JSON objects returned in the response.

 

Well, I am sure you will agree with me when I say that noone has any doubts why Microsoft was so keen on incorporating/embracing the JQuery library into their products.

Microsoft favors JQuery over Ajax Javascript library because of its huge power

Hope it helps!!!!! Email me if you need the source code.

Creating simple and complex animations with JQuery in ASP.Net applications

This another post that is focusing on how to use JQuery in our ASP.Net applications. If you want to have a look at the other posts related to JQuery in my blog click here

We always wanted to have eye-candy web applications and since the first web pages (simple html) were introduced to the world we wanted to have dynamic effects applied to them.

We achieved that using  DHTML (Javascript & CSS).So Javascript made that possible entirely on the client.Then we wanted to have more complex sophisticated animations in our websites.We could do that with Javascript but it was an overwhelming task and we had to find solutions for the cross browser compatibility issues that were surfacing.

The JQuery library makes it really easy to create smooth animations that work in all browsers. Make sure you will not get carried away and avoid annoying animations. Animations are only for enhancing the usability of the application and enhance the user experience.

In this post (with hands on examples) I will demonstrate how to incorporate JQuery to your ASP.Net applications.

Some basic level of knowledge of JQuery is assumed.

Sadly, we canot cover the basics of JQuery in this post so here are a few resources for you to focus on

 

Let's move on with our samples.

1) Launch Visual Studio 2010.  Create an ASP.Net Web application.Choose C# as the development language.Give your application an appropriate name.

2) We want to download and use the latest version of JQuery. We need to download it first. Then we need to remove the version that ships with VS 2010, 1.4.1.We will place inside the Scripts folder the 1.6.3 version of the JQuery library.

3)  Add a new item to your application, a web form. Name it, BasicAnimations.aspx. Do not include the master page. First we need to add some content to the page.

We will create a small table with information regarding Liverpool football players.

We will start with some very basic animations regarding the mouseover, mouseout,click events.

We want to do the following

  • Give the even rows of the table a background color when the page loads for the first time
  • Add a color (background color) as the user hovers over each row
  • Remove the hover color as the user moves out from the row
  • When the user clicks on a row, the background color and the color of the contents of that row should change as well.
  • The user should click a button and then all the rows the user clicked up to that point should get unselected and get back to their original color (as they were when the page was loaded). We want to achieve an inversion of selected rows. Those that the user clicked (changed background color and color) and then by choosing to click this button all the not clicked rows get the same background color as the clicked ones, where the clicked ones revert to their original colours. I hope I make sense....
  • Finally the user should click a button and bring the table back to its original state.

 Let's just assume that those are the effects we need to implement.

4) The markup for the .aspx page follows

<html xmlns="http://www.w3.org/1999/xhtml">
 
<head runat="server">
    <title>Liverpool Football Team Animations</title>
    <link href="Styles/MyStyles.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/jquery-1.6.3.js" type="text/javascript"></script>
 
    <script type="text/javascript">
  
        $(function () {
           
            $('tr:even').addClass('original');
 
 
            $('tr').mouseover(function () {
                $(this).addClass('HighlightHover');
            });
            $('tr').mouseout(function () {
                $(this).removeClass('HighlightHover');
            });
 
           
            $('tr').click(function () {
                $(this).toggleClass('HighlightClick');
            });
          
            $('#Togglebutton').click(function () {
                $('tr').toggleClass('HighlightClick');
            });
          
            $('#Clearbutton').click(function () {
                $('tr.HighlightClick').removeClass('HighlightClick');
            });
        });
    
    
    </script>
</head>
<body>
<h1>Liverpool Football Team</h1>
    <form id="form1" runat="server">
    <div id="DivLive">
        <asp:Table ID="Table1" runat="server"  HorizontalAlign="Center">
        <asp:TableHeaderRow>
        <asp:TableHeaderCell ColSpan="3">Liverpool Squad</asp:TableHeaderCell>
        </asp:TableHeaderRow>
        <asp:TableHeaderRow>
        <asp:TableHeaderCell>Full Name</asp:TableHeaderCell>
        <asp:TableHeaderCell>Position</asp:TableHeaderCell>
        <asp:TableHeaderCell>Date of Birth</asp:TableHeaderCell>
        </asp:TableHeaderRow>
        <asp:TableRow>
        <asp:TableCell>Steven Gerrard</asp:TableCell>
         <asp:TableCell>Midfielder</asp:TableCell>
         <asp:TableCell>30/05/1980</asp:TableCell>
        </asp:TableRow>
         <asp:TableRow>
        <asp:TableCell>Dirk Kuyt</asp:TableCell>
         <asp:TableCell>Striker</asp:TableCell>
         <asp:TableCell>22/07/1980</asp:TableCell>
        </asp:TableRow>
         <asp:TableRow>
        <asp:TableCell>Jamie Carragher</asp:TableCell>
         <asp:TableCell>Defender</asp:TableCell>
         <asp:TableCell>28/01/1978</asp:TableCell>
        </asp:TableRow>
        <asp:TableRow>
         <asp:TableCell>Luis Suarez</asp:TableCell>
         <asp:TableCell>Striker</asp:TableCell>
         <asp:TableCell>24/01/1987</asp:TableCell>
        </asp:TableRow>
        <asp:TableRow>
         <asp:TableCell>Rodriguez Maxi</asp:TableCell>
         <asp:TableCell>MidFielder</asp:TableCell>
         <asp:TableCell>02/01/1981</asp:TableCell>
        </asp:TableRow>
         <asp:TableRow>
         <asp:TableCell>Stewart Downing</asp:TableCell>
         <asp:TableCell>MidFielder</asp:TableCell>
         <asp:TableCell>22/07/1984</asp:TableCell>
        </asp:TableRow>
        </asp:Table>
    </div>
    <br />
    <div id="divButtons">
    <button type="button" id="Togglebutton">Toggle Highlight</button>
	<button type="button" id="Clearbutton">Clear</button>
		</div>
    </form>
</body>
</html>

This is the external stylesheet (MyStyles.css)

h1
{
 text-align:center;
 
}
 
#Table1
 
{
 background-color:#D3D3D3;   
 width:800px;
}
 
table,tdth
{
	
	border1px solid #990000;
}
 
td
 
{
 text-align:center;  
 font-family:Comic Sans MS;
 font-size:0.9em;
  font-style:italic;
}
 
th
{
 font-family:Century;
 font-size:1.2em;
    
}
		
 
		
.original
{
	background-color#99CC66;
}
		
.HighlightHover
{
	background-color#0000FF;
	colorWhite;
	
}
.HighlightClick
{
	background-colorBlue;
	colorYellow;
	
}

5) The markup inside the <body> tags is very easy to follow.

In the <head> section I have references to the external .css file and the JQuery library file.

Inside our Javascript code we start by making sure the function will execute when the DOM is fully loaded.

The $(document).ready(function() {
 
});


is the same as calling:

$(function() {

});

I wanted to mention that because many people do not get that. If you want to have a look at the .ready() method click here.

 $('tr:even').addClass('original');

Then we add a background color to the even rows (using Jquery filters) and the addClass method.

Then for the mouseover and the mouseout I add a new class (HighlightHover),new background color for the mouser over event and then remove(removeClass) that class (and background color) as the user mouses out.Here are the snippets for those 2 functions

$('tr').mouseover(function () {
                $(this).addClass('HighlightHover');
     });
$('tr').mouseout(function () {
                $(this).removeClass('HighlightHover');
     });

Then we need to change color and background color when the user clicks a row

 $('tr').click(function () {
                $(this).toggleClass('HighlightClick');
    });

In this case I use the toggleClass method to apply the class in the row when clicked once and when clicked again to remove that class (HighlightClick)

Then I need to implement the feature where the user should click a button and then all the rows the user clicked up to that point should get unselected and get back to their original color where the unclicked ones get the colors, as if they were clicked by the user one by one. We want basically to have the reverse effect.I use the toggleClass again.

 $('#Togglebutton').click(function () {
                $('tr').toggleClass('HighlightClick');
  });
          

 Finally when the user hits the "clear" button to revert anything back to its original position, I use this bit of code (removeClass method) to achieve that.

 $('#Clearbutton').click(function () {
                $('tr.HighlightClick').removeClass('HighlightClick');
  });

 

6) Run your application and browse to the BasicAnimations.aspx. Have a look of what you achieved so far.Experiment with the page.Try all the events described above. It is pretty cool, isn't it? We have done all that with very very little Javascript code. This code works across all major browsers.I hope that you start  to realise the power of JQuery and why Microsoft is so keen on this lightweight super efficient Javascript Library.

 

7) Let's move on to a more complex animation. Add a new item to your application, a web form. Name it ComplexAnimations.aspx

We will have to add some content to this page. I have added 4 paragraphs from Wikipedia regarding Liverpool football club from Wikipedia. You can copy this text or any other text you want and place it inside a <p> tag.

8) We want to add some animation to the paragraph. We want to add two buttons. By clicking those buttons we want to fade in and fade out the text in the paragraph.

Let me show you how to achieve that.

 

My markup so far looks something like this

    <p id ="LivDesc">
    Liverpool Football Club is an English Premier League football club based in Liverpool, Merseyside......
.............
    </p>
    </div>
 
    <br />
<button type="button" id="FadeOut">Fade Out</button>
<button type="button" id="FadeIn">Fade In</button>

 Inside the <head> section of the.aspx page we have to type the following

 

<script src="Scripts/jquery-1.6.3.js" type="text/javascript"></script>
	<script type="text/javascript">
 
    $(function () {
	$('#FadeOut').click(function () {
		$('#LivDesc').fadeOut('slow');
	});
	$('#FadeIn').click(function () {
	        $('#LivDesc').fadeIn('slow');
	});

 

});
 
	</script>

 

As you can see the javascript code is pretty simple. I am using the fadeOut and fadeIn methods . Run your application and click the buttons to see the effects for yourself.

'slow' can be supplied as a parameter to indicate a duration of 600 milliseconds.

A lot of people like the Toggle effect, where the user hits the same button once and something happens and then hit it again and the opposite happens. We must another button.

  <button type="button" id="Toggle">Toggle</button>

 The javascript code follows

 

    $('#Toggle').click(function () {
	            $('#LivDesc').toggle('slow');
	        });

 I use the toggle() method.

'slow' can be supplied as a parameter to indicate a duration of 600 milliseconds. View the page in the browser and click the Toggle button. See the animation for yourself.

Well, you can have the same effect as "Toggle" by using the hide() and show() methods.

Add two more buttons to the .aspx page

 <button type="button" id="Hide">Hide</button>
 <button type="button" id="Show">Show</button>

 The javascript code follows

  $('#Hide').click(function () {
	$('#LivDesc').hide('slow')
});
  $('#Show').click(function () {
        $('#LivDesc').show('slow');
});

This is very easy Javascript code to achieve this nice animation.

View the page in the browser and click the buttons. See the animation for yourself.

 We can combine some of these effects in the click event of a single button. We add a new button

 <button type="button" id="Complex">Complex animation</button>

 

The Javascript code for the complex animation follows

     $('#Complex').click(function () {
	            $('#LivDesc')
		.fadeOut('slow').delay(1500)
		.fadeIn('slow').delay(1500)
		.slideToggle('slow').delay(1500)
		.slideToggle('slow').delay(1200)
		.fadeTo(1000, 0.20).delay(1200)
		.fadeTo(1200, 1);
 
	        });

9) I use the fadeOut() and fadeIn() methods on the paragraph with a delay of 1.5 seconds.

I use the slideToggle()  which first hides the paragraphs with some motion and then shows it again with some motion and some delay between them.

Then I use the fadeTo() method to adjust the opacity of the paragraphs to 0.2 and then gradually back to 1.

View the page in the browser and click the button. See the animation for yourself.

In this last sample I will use the animate() method to achieve some nice complex animations.This is a very flexible and customisable animation.

This method lets you set targets for CSS properties like top,left,font-size.

Add another web form to your application. Name it MainAnimation.aspx.We will need to add some content and some buttons in our page.

I am going to use the same paragraph as in the previous example.This is the paragraph I want to animate.

 <p id ="LivDesc">
    Liverpool Football Club is an English Premier League football club based in Liverpool, Merseyside......
.............
    </p>
    </div>
 
    <br />

 

10) Add another item on your application, a stylesheet. Name it complex.css. Place a reference of it in the <head> section of the .aspx page.

 The contents of the .css file follow

#LivDesc
{
    
background-color#E2E6DE;
border1px solid #00FFFF;
width700px;
positionabsolute;
top250px;
left100px;
color:Olive;
font-family:Century;
			
}

 

The first animations I would like to do is to add four buttons so I can move the paragraph around on the page.

 Just after the paragraph add four buttons. When clicked those buttons will move the paragraph on the left,right,up,down directions on the page.

<button type="button" id="btnMoveLeft">Move Left</button>
<button type="button" id="btnMoveRight">Move Right</button>
<button type="button" id="btnMoveUp">Move Up</button>
<button type="button" id="btnMoveDown">Move Down</button>

 Now we need to add the javascript code to implement the animations. This is what I have inside the <head> section of the page.

 <script src="Scripts/jquery-1.6.3.js" type="text/javascript"></script>
    <link href="Styles/complex.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript">
        $(function () {

            $('#btnMoveRight').click(function () {
                $('#LivDesc').animate({ left: "+=30px" }, 500);
            });
            $('#btnMoveUp').click(function () {
                $('#LivDesc').animate({ top: "-=30px" }, 500);
            });
            $('#btnMoveDown').click(function () {
                $('#LivDesc').animate({ top: "+=30px" }, 500);
            });
 

 
        });
	</script>

It is very easy to see what I do here. I attach the click event to those buttons and then use the animate method to move the paragraph accordingly. Note that the original values of (top and left positioning) are defined in the .css file. The duration of every movement is (500 ms) 0.5 seconds.

Run your application and click on the buttons. You will see the desired effects.

11) We can chain those movement animations together.That basically means is that we chain together multiple calls of the animate() method.

We have to add another button in  our page.

 <button type="button" id="btnChain">Move all over</button>

 This is the javascript code we must place in the <script> block

          $('#btnChain').click(function () {
                $('#LivDesc').animate({
                    top: "500px",
                    left: "100px"
                }, 3000)
		.animate({
		top: "600px",
		left: "150px"
		}, 2000)
		.animate({
		top: "200px",
	        left: "500px"
		}, 1000);
            });

 

View the page in the browser and see the desired effect when clicking the button.

Νow I would like to show the final animation, which gives the paragraph the bounce effect.

We have to add another button in  our page.

 <button type="button" id="btnBounce">Bounce Me!!!</button>
 
 This is the javascript code we must place in the <script> block
 
 $('#btnBounce').click(function () {
                $('#LivDesc').animate({ padding: "60px" }, 'slow')
.animate({ paddingLeft: "2px", paddingTop: "2px" }, 'slow')
.animate({ paddingLeft: "60px", paddingTop: "60px", paddingRight: "2px"
paddingBottom: "2px" }, 'slow')
.animate({ paddingLeft: "2px", paddingTop: "2px", paddingRight: "60px",
 paddingBottom: "60px" }, 'slow')
.animate({ paddingLeft: "60px", paddingTop: "60px" }, 1000)
.animate({ padding: "0px" }, 1000);
     }); 

This is another example of multiple calls (chained) to the animate() method.I do that by changing the values of the padding values.

View the page in the browser and see the desired effect when clicking the button. 

There are some limitations to the animate() method. We can't animate colors for example.We can only animate and set single numeric CSS properties.Shorthand CSS properties are not supported like border,margin,padding.

Email me if you need the source code!!!

Hope it helps!!!!

Using the AutoCompleteExtender control in an Ajax ASP.Net application

In this post I will talk about Ajax again.This time we will use an extender to ajaxify our application.I am going to use the AutoCompleteExtender extender together with a textbox. Inside the extender control I will call a web service (a service method) and I will pass it whatever the user types in the textbox.

Then the method will search in a .xml file and return only those results that match the input of the user.In order to better understand what I mean think of this example something like the Google Suggest like auto-complete features. This is very useful for the user since he can select valid data for the textbox and to prevent him from typing invalid data.

You will need to have the Ajax Control Toolkit in order to complete this sample. The toolkit is a library of Ajax-enabled server side controls.They have much richer client side functionality than the other ASP.Net controls.To be more specific they encapsulate client-side CSS and Javascript.

If you want to see how you can download and install the Ajax Control Toolkit (as part of the Visual Studio 2010 tool) you can click here. Download the binary version and not the source one. The source version is only useful only if you want to extend the toolkit.The toolkit was not developed by Microsoft. It is a collaborative effort and the source code is placed on the open source project repository website , codeplex.com.Ajax toolkit is a brilliant example on how developer's skills and commitment can benefit the community.

A Control Extender adds functionality to another control. Extenders extend existign UI elements. Extenders can be applied to a variety of ASP.Net controls and can be applied to existing controls in existing applications. The extender controls and their class ExtenderControl inherits from the Control base class.

1) Launch Visual Studio 2010 (express edition will do). Create a new ASP.Net Web application and give it an appropriate name. Choose C# as the development language.

2) Add a new item in your application, a web form. Name it Footballers.aspx. Yes, you guessed it, we will query an xml file with football related data.

3) Add a textbox control on the form. Name it FootballTextBox.Add a ScriptManager control on the page.

4) Add a new item to your application, an .xml file. Name it Footballers.xml. The code for the file follows.

<?xml version="1.0" encoding="utf-8" ?>
<Footballers>
    <footballer name ="Henderson" />
    <footballer name ="Adam" />
    <footballer name ="Carragher" />
    <footballer name ="Carroll" />
    <footballer name ="Kuyt" />
    <footballer name ="Lucas" />
    <footballer name ="Agger" />
    <footballer name ="Aquilani" />
    <footballer name ="Aurelio" />
    <footballer name ="Bellamy" />
    <footballer name ="Coady" />
    <footballer name ="Coates" />
    <footballer name ="Cole" />
    <footballer name ="Downing" />
    <footballer name ="Flanagan" />
    <footballer name ="Gerrard" />
    <footballer name ="Maxi" />
    <footballer name ="Meireles" />
    <footballer name ="Srktel" />
    <footballer name ="Spearing" />
    <footballer name ="Sterling" />
    <footballer name ="Suarez" />
    <footballer name ="Wilson" />
    <footballer name ="Wisdom" />
</Footballers>

 5) Add a new item to your application, a web service.Name it footballer.asmx. In the code behind (footballer.asmx.cs) of this file we will have to uncomment this line of code

[System.Web.Script.Services.ScriptService]

The whole code for the footballer class (that inherits from the WebService class) follows


[System.Web.Script.Services.ScriptService]
public class footballer: System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod]
public string[] GetFootballers(string prefixText, int count)
	{
	XmlDocument doc = new XmlDocument();
	string path = HttpContext.Current.Server.
	MapPath("~/App_data/Footballers.xml");
	doc.Load(path);
	XmlNodeList footballerData = doc.GetElementsByTagName("footballer");
 
	List<string> footballers = new List<string>();
	foreach (XmlNode footballer in footballerData)
	{
	string footballerName = footballer.Attributes["name"].Value;
 
	if (footballerName.ToLower().StartsWith(prefixText.ToLower()))
	footballers.Add(footballerName);
 
	if (footballers.Count >= count)
	break;
	}
 
	return footballers.ToArray();
}
}
}

 I will explain what I do in the code above. I am creating an XmlDocument object.Then I get the path of the .xml file and load the file.Then I create a XmlNodeList object that holds the footballer elements.Then I create a list of strings object (footballers). Then I loop through the elements and for each element I get the attribute name value.Then I check to see if that name attribute value matches the input (characters) the user typed in the textbox.If it is true I add that name value to the array and finally I return that array of matching footballers. It is not difficult to understand the code for this method.

5) Let me show you the markup for the AutoCompleteExtender extender.First select the Textbox control and then click the smart tag ( Add Extender) and from the available extenders choose AutoCompleteExtender and click OK.Then complete markup follows.

 

	<form id="form1" runat="server">
	<div>
		<asp:ScriptManager ID="ScriptManager1" runat="server">
		</asp:ScriptManager>
		<asp:TextBox ID="FootballTextBox" runat="server"></asp:TextBox>
		<asp:AutoCompleteExtender 
			ID="FootballTextBox_AutoCompleteExtender" 
			runat="server" DelimiterCharacters=""
			Enabled="True" ServicePath="footballer.asmx"
			ServiceMethod="GetFootballers"
			MinimumPrefixLength="2" 
			TargetControlID="FootballTextBox">
		</asp:AutoCompleteExtender>
	</div>
	</form>

 I will explain some of the properties of the AutoCompleteExtender. ServicePath property is set to the web service file. The ServiceMethod property is set to the method we just described above.The MinimumPrefixLength property is set to 2, which defines how many characters the user must insert before asynchronous requests are triggered back to the server.

 

6) Run your application and type the letters "wi". When you do that all the footballer names that start with "Wi" should appear in the dropdownlist.

Have a look at the picture below.

 

I hope you understood how important extender controls are and how more responsive our application becomes. We have partial/asynschronous postbacks to the server without the page flickering. If you want to see the communication that takes place you can donwload Fiddler (works something like a web listener/debugger) here. You can see exactly what happens between the client and the server.You can see the requests, the responses, the headers, the actual HTML sent to the client.

Have  a look at the picture below.

 

Email me if you want the source code!!!

Hope it helps!!!

Investigating Ajax history in ASP.Net applications

In this post I would like to talk about Ajax history in ASP.Net applications and how it works.The problem with ASP.Net Ajax applications is that the browser's back and forward buttons do not store the history of the page.

The browser recognises only URLs. When having Ajax enabled applications and Ajax requests, the page's URL does not change.As a result of that the browser saves nothing in its history cache.

In a nutshell, browser back and forward buttons do not work, are disabled.

As always I will demonstrate the inner workings of Ajax history with a hands on example.I will need an instance of SQL Server running in my machine and a database.

I assume that you have access to a version of SQL Server and NorthWind database. 

If you do not, you can download and install the free SQL Server Express edition from here.

If you need the installation scripts for the NorthWind database click  here.I have SQL Server 2008 R2 Developer edition installed my machine.

I will create a very simple ASP.Net application and then ajaxify it.In this example you will see how to use a master-detail form without writing any code.This is not the best way to do it but it is good enough for now and for our example.

I will have a dropdownlist control that contains the categories of the products and then as the user selects a category, the products (that will be presented through a GridView control) will get displayed on the screen. I will use SqlDataSource controls.

1) Launch Visual Studio 2010 (express edition will work fine). Create an ASP.Net Web Application from the available templatesand choose a suitable name for it. Choose C# as the development language.

2) Add a new item on your application, a web form. Name it products.aspx. Drop a GridView and a DropDownlist on the products.aspx. Leave the default names.

3) Add a SqlDataSource web server control on the page.Click on the smart tag , of the control and choose Configure Data Source. Create a new connection to the database by specifying the server name and the database name.Then follow the steps of the wizzard. Select the Categories table from the available tables. Choose only CategoryID and CategoryName from the available columns.The Select statement should look something like this

SELECT DISTINCT [CategoryID], [CategoryName] FROM [Categories] ORDER BY [CategoryName]

then finish the wizzard.

We must then associate this SqlDataSource with the DropDownList control

The complete markup (so far) follows

 

 <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
        DataSourceID="SqlDataSource1" DataTextField="CategoryName" 
        DataValueField="CategoryID">
    </asp:DropDownList>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT DISTINCT [CategoryID], [CategoryName] FROM 
[Categories] ORDER BY [CategoryName]">
</asp:SqlDataSource>

4) Add another  SqlDataSource web server control on the page.Click on the smart tag , of the control and choose Configure Data Source.

Use the same connection string as before and this time choose the Products table from the available objects and choose only the Product columns (ProductID,ProductName,UnitsInStock).Then click the WHERE button on the wizzard.Select the CategoryID and set the Source to Control. The CategoryID value will be set from whatever value the user picks in the DropDownList control.

 Have a look at the picture below, to see the actual settings

 

Then you can click OK , then click Next and then finish the wizzard. The complete markup so far is (inside the <form> tags)

 <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
        DataSourceID="SqlDataSource1" DataTextField="CategoryName" 
        DataValueField="CategoryID">
    </asp:DropDownList>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT DISTINCT [CategoryID], [CategoryName] FROM 
[Categories] ORDER BY [CategoryName]"></asp:SqlDataSource>
    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
        AllowSorting="True" AutoGenerateColumns="False" 
        BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" 
     CellPadding="2" DataKeyNames="ProductID" DataSourceID="SqlDataSource2" 
        ForeColor="Black" GridLines="None">
        <AlternatingRowStyle BackColor="PaleGoldenrod" />
        <Columns>
            <asp:CommandField ShowSelectButton="True" />
            <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
          InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
            <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
            SortExpression="ProductName" />
         <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" 
           SortExpression="UnitsInStock" />
        </Columns>
        <FooterStyle BackColor="Tan" />
        <HeaderStyle BackColor="Tan" Font-Bold="True" />
        <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" 
            HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
        <SortedAscendingCellStyle BackColor="#FAFAE7" />
        <SortedAscendingHeaderStyle BackColor="#DAC09E" />
        <SortedDescendingCellStyle BackColor="#E1DB9C" />
        <SortedDescendingHeaderStyle BackColor="#C2A47B" />
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT [ProductID], [ProductName], [UnitsInStock] FROM 
[Products] WHERE ([CategoryID] = @CategoryID) ORDER BY [ProductName]">
        <SelectParameters>
            <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID" 
                PropertyName="SelectedValue" Type="Int32" />
        </SelectParameters>
    </asp:SqlDataSource>

 

5) Add a link to the products page to the Default.aspx page.Run your application and see the products being displayed according to the user's selection in the DropDownList control.

6) Now let's ajaxify our application. The contents of the DropDownList control are not likely to change.Those contents should not be part of the partial update and should not get posted back to the server.

We will add a ScriptManager control on the Products.aspx page. Then we will add an UpdatePanel control on the Products.aspx page.Inside there we will have the second SqlDatasource control and the GridView control.Now if you run your application it will work fine (as before) but still the page does not behave like an ajaxified page. We can see flickering and it is less responsive than it should be. We will a use a Triggers element, an asynchronous postback trigger inside the UpDatePanel element  to fix that.Basically we need a way to indicate that the SelectedIndexChanged event of the DropDownList control should trigger an Ajax request to update the page.The markup for the Triggers element follows (snippet)

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList1" 
EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
.... 

 

 7) The complete markup for the page follows

<body>
    <form id="form1" runat="server">
    <div>
    
       <a href="Default.aspx">Default.aspx</a></div>
       
       <br/> 
       <asp:ScriptManager ID="ScriptManager1" runat="server">
		</asp:ScriptManager>
    
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
        DataSourceID="SqlDataSource1" DataTextField="CategoryName" 
        DataValueField="CategoryID">
    </asp:DropDownList>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT DISTINCT [CategoryID], [CategoryName] FROM 
[Categories] ORDER BY [CategoryName]"></asp:SqlDataSource>
        <br />
        <br />
 
 
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <Triggers>
	<asp:AsyncPostBackTrigger ControlID="DropDownList1" 
EventName="SelectedIndexChanged" />
        </Triggers>
        <ContentTemplate>
    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
        AllowSorting="True" AutoGenerateColumns="False" 
        BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" 
        CellPadding="2" DataKeyNames="ProductID" DataSourceID="SqlDataSource2" 
        ForeColor="Black" GridLines="None">
        <AlternatingRowStyle BackColor="PaleGoldenrod" />
        <Columns>
            <asp:CommandField ShowSelectButton="True" />
            <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
           InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
            <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
          SortExpression="ProductName" />
            <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" 
           SortExpression="UnitsInStock" />
        </Columns>
        <FooterStyle BackColor="Tan" />
        <HeaderStyle BackColor="Tan" Font-Bold="True" />
        <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" 
            HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
        <SortedAscendingCellStyle BackColor="#FAFAE7" />
        <SortedAscendingHeaderStyle BackColor="#DAC09E" />
        <SortedDescendingCellStyle BackColor="#E1DB9C" />
        <SortedDescendingHeaderStyle BackColor="#C2A47B" />
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT [ProductID], [ProductName], [UnitsInStock] FROM 
[Products] WHERE ([CategoryID] = @CategoryID) ORDER BY [ProductName]">
        <SelectParameters>
            <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID" 
                PropertyName="SelectedValue" Type="Int32" />
        </SelectParameters>
    </asp:SqlDataSource>
 
    </ContentTemplate>
   </asp:UpdatePanel>
    </form>
</body>

8) Run your application again and see the page fully ajaxified. Select various options from the DropDownList control. The URL in the browser does not change.The Back and Forward buttons of the browser are disabled.Now click on the Defaul.aspx link and you will get to the home page.Now go to the Products.aspx page again.If you keep selecting different categories and then click the Back button.You will get back to the default.aspx page and not the last category with the products.So we have a problem. Ajax history feature comes to the rescue.It is not enabled by default.You have to implement page state.In this example we have to record state for each category the user selects.In this example we should create a history point each time the user selects a new product category.A history point is a save state that you can navigate back to.

9) Let's see the changes we should make on the products.aspx page.We should make some changes to the ScriptManager web server control.The new markup should look like this.

 

<asp:ScriptManager ID="ScriptManager1" runat="server" EnableHistory="true" 
        EnableSecureHistoryState="false" onNavigate="ScriptManager1_Navigate">
  </asp:ScriptManager>

We set the EnableHistory attribute to True.We also must specify a methood for the onNavigate event.This is the event that fires when the user navigates between pages.

We also have to place the DropDownList control and it respective SqlDataSource control inside the UpdatePanel control. If we want to have Ajax history enabled those controls have to be moved inside the UpdatePanel control.The final markup for the page follows

<body>
    <form id="form1" runat="server">
    <div>
    
  <a href="Default.aspx">Default.aspx</a></div>
  <asp:ScriptManager ID="ScriptManager1" runat="server" EnableHistory="true" 
  EnableSecureHistoryState="false" onNavigate="ScriptManager1_Navigate">
</asp:ScriptManager>
 
       
 
 
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <Triggers>
	<asp:AsyncPostBackTrigger ControlID="DropDownList1" 
        EventName="SelectedIndexChanged" />
	</Triggers>
        <ContentTemplate>
    <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" 
        DataSourceID="SqlDataSource1" DataTextField="CategoryName" 
        DataValueField="CategoryID" 
        onselectedindexchanged="DropDownList1_SelectedIndexChanged">
    </asp:DropDownList>
    <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT DISTINCT [CategoryID], [CategoryName] FROM 
[Categories] ORDER BY [CategoryName]"></asp:SqlDataSource>
    <asp:GridView ID="GridView1" runat="server" AllowPaging="True" 
        AllowSorting="True" AutoGenerateColumns="False" 
        BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" 
        CellPadding="2" DataKeyNames="ProductID" DataSourceID="SqlDataSource2" 
        ForeColor="Black" GridLines="None">
        <AlternatingRowStyle BackColor="PaleGoldenrod" />
        <Columns>
            <asp:CommandField ShowSelectButton="True" />
            <asp:BoundField DataField="ProductID" HeaderText="ProductID" 
         nsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
            <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
                SortExpression="ProductName" />
            <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock" 
                SortExpression="UnitsInStock" />
        </Columns>
        <FooterStyle BackColor="Tan" />
        <HeaderStyle BackColor="Tan" Font-Bold="True" />
        <PagerStyle BackColor="PaleGoldenrod" ForeColor="DarkSlateBlue" 
            HorizontalAlign="Center" />
        <SelectedRowStyle BackColor="DarkSlateBlue" ForeColor="GhostWhite" />
        <SortedAscendingCellStyle BackColor="#FAFAE7" />
        <SortedAscendingHeaderStyle BackColor="#DAC09E" />
        <SortedDescendingCellStyle BackColor="#E1DB9C" />
        <SortedDescendingHeaderStyle BackColor="#C2A47B" />
    </asp:GridView>
    <asp:SqlDataSource ID="SqlDataSource2" runat="server" 
        ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
        SelectCommand="SELECT [ProductID], [ProductName], [UnitsInStock] FROM 
[Products] WHERE ([CategoryID] = @CategoryID) ORDER BY [ProductName]">
        <SelectParameters>
            <asp:ControlParameter ControlID="DropDownList1" Name="CategoryID" 
                PropertyName="SelectedValue" Type="Int32" />
        </SelectParameters>
    </asp:SqlDataSource>
 
    </ContentTemplate>
   </asp:UpdatePanel>
    </form>
</body>

 

10) We have to add some code in the code behind files. I am going to write some code for the SelectedIndexChanged event of the DropDownList control.We are going to create/save a history point every time the user makes a selection. We also have to check whether we have an asynschronous request and we are not navigating to another page.

The code follows

protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
       //check whether we have an asynschronous request and we are 
      //not navigating to another page.

            if (ScriptManager1.IsInAsyncPostBack
                && !ScriptManager1.IsNavigating)
            {
 //create a unique title for the page

                string mytitle = "Northwind Products for the category: "
                    + DropDownList1.SelectedItem.Text;
                this.Title = mytitle;
                Page.Title = mytitle;
     //create a history point

                ScriptManager1.AddHistoryPoint("thecategory",
                    DropDownList1.SelectedIndex.ToString(),
                    mytitle);
            }
        }

 11) We also have to write some code for the Navigate event of the ScriptManage control. This event fires when the user navigates to an item in the browser history list.

So when we hit the Back button in the browser, we have to get the category ID of the products and pass it to the SelectedIndex property so the products will be filtered according to the new selection (as a part of the Back button operation)

protected void ScriptManager1_Navigate(object sender, HistoryEventArgs e)
        {
            string indexStr = e.State["thecategory"];
            if (string.IsNullOrEmpty(indexStr))
                DropDownList1.SelectedIndex = 0;
            else
            {
                int index = Convert.ToInt32(indexStr);
                DropDownList1.SelectedIndex = index;
            }
 
        }

 12) Run your application and select different options from the dropdownlist control. Then note that the Back and Forward buttons are enabled. Move Back and Forward using the browser buttons.Note that now we have history enabled and we can move to the previous and next product categories.

Have a look at the picture below.

 

Email me if you need the source code.

Hope it helps !!!

 

Importing html from the server using JQuery Ajax functions

In this post I would like to talk about the various Ajax features-functions available to us when incorporating JQuery into our applications.We are going to investigate how we can use those JQuery Ajax functions to get data from the server.

This post will not be an introduction to Ajax.If you want to see some other posts of mine regarding Ajax have a look here.

In order to follow what I am about to say in this post, I assume that you know what JQuery is and have a basic understanding of how to traverse the DOM or handle events with JQuery.

You can find more posts regarding JQuery by clicking here.

JQuery has Ajax features built-in out of the box. Another point to remember is that JQuery allows Ajax requests to be made from a page.

I will start with a simple example. I will show

1) Launch Visual Studio 2010 (express edition will also work) and create a new website.Choose a suitable name for your website

2) Inside the Scripts folder you can see the Jquery files

3) Add a new item to your web site, an html page.Name it appropriately. I have named it LoadHtmlFromServer.htm.Inside this page we will call another html page that also resides from the server.

4) The html markup for my html page is following

<!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>
    <title>Load HTML Content from the Server using JQuery</title>
   
 
 
</head>
<body>
 
 
<h1>Load HTML Content from the Server using JQuery</h1>
<br />
<button id="niceButton">Click here to load HTML from the Server!!!!</button>
<div id="maindiv"></div>
 
 
 
</body>
</html>

 5) Add another item to your website, an html page. I have named mine jqueryintro.htm. The html markup for my html page is following

<!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>
    <title></title>
</head>
<body>
<div>jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing,
 event handling, animating, and Ajax interactions for rapid web development. <strong>
jQuery is designed to change the way that you write JavaScript.</strong>
</div>
 
<div id="new">
 
 
<p><h3>Download jQuery</h3>
 
This is the recommended version of jQuery to use for your application. The code in
 here should be stable and usable in all modern browsers. </p>
</div>
 
</body>
</html>


6) I want to load the contents of the jqueryintro.htm in the "maindiv" ID, when the user clicks the button.I will do that by using the load() JQuery Ajax function.We will use this function to make a request to the server.

7) We have to add the following javascript/jquery code to the head section of the LoadHtmlFromServer.htm

 <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    
 <script type="text/javascript">
   $(document).ready(function () {
     $('#niceButton').click(function () {
              
      $('#maindiv').load('jqueryintro.htm');
           });
       });
 </script>

You can donwload a newer version of the JQuery library if you want. I am using 1.4.1 in this example.

8) View your page on the browser and click the button. When you do that you will see the contents of the jqueryintro.htm injected to the maindiv ID. So we loaded HTML content from the server and placed it inside a DOM element on another page.

I am using the .load() method in this example. Have a look at the official documentation for the definition of this method.

Basically this function adds the specified file from the server and returns its HTML contents. We assign those contents to the maindiv ID.This method executes when I click the button. As you see I attach the click event to the button of ID niceButton. As you type this code you will notice that you have full Intellisense.

9) Now let's assume that we wanted to get only part of the HTML page (queryintro.htm) and place it in the DOM element - maindiv ID of another page.Let's say we want to get only the data inside the div with the ID = new from the jqueryintro.htm and still place it in the maindiv ID of the LoadHtmlFromServer.htm.We have to make a tiny little change in our JQuery code.Instead of this line

$('#maindiv').load('jqueryintro.htm');
we replace it with this one
$('#maindiv').load('jqueryintro.htm #new'); 

10) View again your page (LoadHtmlFromServer.htm) on the browser and click the button. When you do that you will see the only the contents of the <div id ="new"> injected to the maindiv ID of the LoadHtmlFromServer.htm page.The way it works is that it downloads the whole html file and then applies the filter for only the part of the html file that we are interested in.

 

More Posts