AKA Marketing.com Logo

Blogged thoughts, is our web blog. Expect views, opinion, rants and tirades about everything and anything 

« Home / Services / Forums »         Organic Search Engine Optimization (SEO) Solutions. Call now on +00-353-879807629

Subscribe to our SEO / IT related blog by entering your email address below

Blogged thoughts

| by the www.akamarketing.com team

Archive for the 'ASP.NET' Category


Reordering columns in a DataTable

Tuesday, January 29th, 2008

Recently while working in my Data Access Layer (DAL) I pulled data from two different databases and combined them into a .Net DataTable before returning that DataTable to my business logic layer (BAL) for.. well business logic stuff. Since I could not find an AddAt() method for adding columns at a specific index I had to try and find a way to reorder columns after adding them. I found the solution on forums.asp.net and it’s actually very easy to do. Suppose you had a DataTable named ‘dt’ and column named ‘Staff Number’ which you wanted to be in at column/index 0 in your datatable. The following line of code is all it takes.

dt.Columns[“Staff Number”].SetOrdinal(0);The columns that follow ‘Staff Number’ will all shift across by 1. Incidentally DataTable.Columns[] has two overloads, one which takes a zero-based index of the column to return and another that takes the column name of the column to return. While accessing columns via index numbers is quicker it’s not recommended as it’s too difficult to maintain and read. Imagine for instance I had code which accessed various columns from the ‘dt’ DataTable via an index number and then I realised that I wanted my ‘Staff Number’ column to be first and thus set its index or Ordinal to 0, I would then have to change my index based statements for all columns that were shifted by 1. Since this has the potential to be a royal pain and since my development team would rather read dt.Columns[”COLUMNNAME”]; than dt.Columns[INDEXNUMBER]; I always recommend using Column names for accessing data from things like DataTables, DataSets and SQL statements.

The columns that follow ‘Staff Number’ will all shift across by 1. Incidentally DataTable.Columns[] has two overloads, one which takes a zero-based index of the column to return and another that takes the column name of the column to return. While accessing columns via index numbers is quicker it’s not recommended as it’s too difficult to maintain and read. Imagine for instance I had code which accessed various columns from the ‘dt’ DataTable via an index number and then I realised that I wanted my ‘Staff Number’ column to be first and thus set its index or Ordinal to 0, I would then have to change my index based statements for all columns that were shifted by 1. Since this has the potential to be a royal pain and since my development team would rather read  than  I always recommend using Column names for accessing data from things like DataTables, DataSets and SQL statements.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • YahooMyWeb
  • Reddit
  • Simpy
  • De.lirio.us
  • StumbleUpon
  • Technorati
  • Netscape
  • Spurl
  • blogmarks
  • blinkbits
  • SphereIt
  • Slashdot
  • Ma.gnolia

.Net Framework Generics overview

Sunday, January 27th, 2008

I’m using .NET Generics a lot lately in my code so I thought I’d give a quick overview of what they are and what the advantages of using them while developing are. I like About.com’s definition of them and thus I’ll offer it here:

“Generics is a form of abstraction in developing code. Instead of writing a function or a class for a particular type, it can be written generally to use any type. When an instance of the generic class is instantiated, the type is specified.”

Generics have been around in other programming environments for a while however they are new to the 2.0 version of the .NET framework. In the framework they are used mostly by various collection classes, which are used to store items in memory for later retrieval. In C# creation of a generic collection such as a List requires the use of angle brackets (< >) within which you specify the specific type or types you want to use. The line below instantiates a List set up to store ints only:

  1. List<int> intList = new List<int>();

intList can now be used just like any regular non generic collection. Any attempt by the developer to add anything other than an int to the intList collection will result in a compile time error, thus generics are said to be type safe. Generic type safety is discussed next.

Generics offer a number of advantages including type safety, more elegant code and alleged performance improvement.

Type Safety
Generics provide type safety as once a generic class, interface etc. is instantiated with a specific type or types the framework will not allow your code to compile if you then try to inadvertently use a wrong type(s) with your class, interface etc. Compare this with say using a non generic object such as an ArrayList. Since an ArrayList stores instances of the object class you can store any .Net object as everything derives from object.

Imagine intending to use an ArrayList to store strings but you mistakenly also store a int. The compiler will not complain about this, however when you go to retrieve objects from the ArrayList and attempt to cast each of the objects to strings the runtime will throw an InvalidCastException error as you will have attempted to cast an int to an string. Here’s some C# code which should illustrate this a little better:

  1. ArrayList stringList = new ArrayList();
  2. stringList.Add(“1″);
  3. stringList.Add(“2″);
  4. stringList.Add(3);
  5.  
  6. foreach (string i in stringList) //runtime error as collection contains an int
  7. {
  8. string theString = i;
  9. }

As ArrayList is not a type safe class the above code error will not be caught by the compiler. It will however throw a runtime error as you are attempting to cast an int object to a string object. Now see equivalent code using List<>, the generic version of the ArrayList class.

  1. List<string> stringList = new List<string>();
  2. stringList.Add(“1″);
  3. stringList.Add(“2″);
  4. stringList.Add(3);
  5.  
  6. foreach (string i in stringList)
  7. {
  8. string theString = i;
  9. }

Again your attempting to add an int when your purpose is to add only strings. This time however because you have specified a type (string) at creation time, the compiler knows that stringList.Add(3); is invalid and comes back with The best overloaded method match for ‘System.Collections.Generic.List.Add(string)’ has some invalid arguments error message meaning this section of your code is type safe and will never throw an invalid cast type of exception at runtime.

More elegant code & Performance Improvement.
Microsoft lists performance improvement as a benefit of using generics due to the fact that since you specify your correct type or types at time of creation for an object there is no need to use casting as you can be guaranteed your object contains/uses items of a certain type. Casting requires boxing and unboxing. Boxing relates to converting a value type to a reference type while unboxing relates to converting a reference type to a value type. Both steal processor time and slow performance. Many developers however conclude that the performance benefit from using generics is negligible.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • YahooMyWeb
  • Reddit
  • Simpy
  • De.lirio.us
  • StumbleUpon
  • Technorati
  • Netscape
  • Spurl
  • blogmarks
  • blinkbits
  • SphereIt
  • Slashdot
  • Ma.gnolia

Cannot have multiple items selected in a DropDownList

Sunday, January 20th, 2008

I said I’d share this information about how to resolve this error since it took me almost a whole day to fix it. The ‘Cannot have multiple items selected in a DropDownList‘ exception will be thrown when the developer attempts to select a ListItem in a DropDownList when an item in that same DropDownList has already been selected earlier in previous code.

When searching on Google and the forums.asp.net site most of the suggested fixes to this problem suggested explicitly deselecting all selected items in a dropdown before selecting another. This can be done via something like ddl.clearselection() or ddl.SelectedIndex = -1. It seemed like a fairly logical approach, however it did not work for me, no matter what variation of deselection I tried.

On further investigation, it seemed the problem stemmed from the fact that I was adding the same ListItem to multiple dropdowns like so:

ListItem areaItem = new ListItem(Areas.Rows[i][0].ToString(),Areas.Rows[i][0].ToString());
ddlArea.Items.Insert(i, areaItem);
ddlArea2.Items.Insert(i, areaItem);
ddlArea3.Items.Insert(i, areaItem);
ddlArea4.Items.Insert(i, areaItem);
ddlArea5.Items.Insert(i, areaItem);

but because a ListItem object is a reference object when I changed the selectedItem (and by doing so set a particular ListItems selected property to true) property of say ddlArea4 I also changed it in all the other dropdowns which contained the ListItem which was now selected. Remember reference objects do not keep a copy of an object they simply store a reference to the original object, thus a change in one dropdown list was leading to a change in all so code like the following which aims to explicitly deselect items before selecting another would not work:

ddlArea4.ClearSelection();
ddlArea4.SelectedIndex = -1;
ddlArea4.Items.FindByValue(itdp.Rows[2][1].ToString()).Selected = true; //the ListItem that this will select is present in multiple dropdowns, if any of them have anything selected an error will be thrown

The solution to the problem is to create new instances of ListItems for each option you need to add to dropdown lists, so instead of the first bit of code above, I tried something like:

ddlArea.Items.Add(new ListItem(Areas.Rows[i][0].ToString(),Areas.Rows[i][0].ToString()));
ddlArea2.Items.Add(
new ListItem(Areas.Rows[i][0].ToString(),Areas.Rows[i][0].ToString()));
ddlArea3.Items.Add(new ListItem(Areas.Rows[i][0].ToString(),Areas.Rows[i][0].ToString()));
ddlArea4.Items.Add(
new ListItem(Areas.Rows[i][0].ToString(),Areas.Rows[i][0].ToString()));
ddlArea5.Items.Add(new ListItem(Areas.Rows[i][0].ToString(),Areas.Rows[i][0].ToString()));

It meant when I selected a particular ListItem in a particular dropdown only the one ListItem and dropdown was affected. It worked well and it even allowed me to remove the extra deselection logic which in this case it turned out I did not need.

This was quite an uncommon scenario that led to this problem and tracking down the solution was difficult. I think in over 90% of cases the problem with the “Cannot have multiple items selected in a DropDownList” error would come from the developer trying to select more than one item in a DropDownList in a more obvious way such as simply having two or more .Selected = true statements perhaps in different parts of his or her code without realising. Therefore always give something like ClearSelection() or SelectedIndex = -1 a go first before thinking too hard about this problem, it will most likely resolve it.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • YahooMyWeb
  • Reddit
  • Simpy
  • De.lirio.us
  • StumbleUpon
  • Technorati
  • Netscape
  • Spurl
  • blogmarks
  • blinkbits
  • SphereIt
  • Slashdot
  • Ma.gnolia

Repeater paging with an SqlDataSource in ASP.Net

Friday, August 17th, 2007

The ASP.Net repeater control has over the last while become one of my favourite controls due to the fact it can be highly customised because it’s a templated control. Two shortcomings with the current implementation of the repeater control however are its lack of paging and sorting capabiltites. Of these I believe paging is perhaps the more desirable feature and thus I will now provide an outline of how to implement paging with a repeater using an SqlDataSource. I’ve chosen to work with an SqlDataSource as this I imagine is the most common underlying data source used with repeaters. 

PagedDataSource class
The most popular way ASP.Net developers enable repeaters to page through large amounts of results is with the help of the PagedDataSource class. This is a class which

Encapsulates the paging-related properties of a data-bound control (such as DataGrid, GridView, DetailsView, and FormView) that allow it to perform paging and is used by control developers when providing paging support to a custom data-bound control.

Since this class can be used to provide paging support to custom data-bound controls it can of course be used by built in data-bound controls such Repeaters and DataLists to provide the same support. If you look on the MSDN page which I have linked to above you’ll notice however that the class implements the ICollection interface. This means that any underlying source you want to feed into the PagedDataSource class (which in turns feeds into the repeater itself) must also implement ICollection. The SqlDataSource class does not implement this interface and thus we must put the data into some class that does implement ICollection, in this case we are using a DataView. OK lets look the c# code behind.

  1. public partial class _Default : System.Web.UI.Page
  2. {
  3.     PlaceHolder innerPlaceHolder = new PlaceHolder();
  4.     protected void Page_Load(object sender, EventArgs e)
  5.     {
  6.         Session[“pageNumber”] = 1;
  7.         Page_with_Repeater();
  8.         int totalResults = (int)Session[“totalResults”];
  9.  
  10.         //five represents the page size - could you session/viewstate
  11.         //to avoid hardcoding but for this sample it’s fine.
  12.         float numOflinks = ((float)totalResults / 5);
  13.        
  14.         //determine how many links to create/display
  15.         if (numOflinks % 1 == 0) numOflinks = (int)numOflinks;
  16.         else if(numOflinks % 1 != 0) numOflinks = (int)numOflinks + 1;
  17.        
  18.         for (int i = 1; i < numOflinks+1; i++)
  19.         {
  20.             LinkButton PagingLink = new LinkButton();
  21.             PagingLink.ID = “pagelink” + i.ToString();
  22.             PagingLink.Text = i.ToString();
  23.             PagingLink.Visible = true;
  24.             PagingLink.CommandArgument = i.ToString(); //used to detect result page required
  25.             PagingLink.Command += new CommandEventHandler(PagingLink_Command);
  26.             innerPlaceHolder.Controls.Add(PagingLink);
  27.         }
  28.     }
  29.  
  30.     public void Page_with_Repeater()
  31.     {
  32.         //SqlDataSource does not implement ICollection and
  33.         //thus will not work with PageDataSource we therefore use
  34.         //a DataView instead which implements all required Interfaces
  35.         DataSourceSelectArguments arg = new DataSourceSelectArguments();
  36.         DataView dv = (DataView)SqlDataSource1.Select(arg);
  37.  
  38.         //Instantiate an instance of PagedDataSource
  39.         //and sets its main properties
  40.         PagedDataSource PagedResults = new PagedDataSource();
  41.         PagedResults.DataSource = dv;
  42.         PagedResults.AllowPaging = true;
  43.         PagedResults.PageSize = 5; //CHANGE THIS ABOVE TOO
  44.  
  45.         int pageIndex;
  46.         Int32.TryParse(Session[“pageNumber”].ToString(), out pageIndex);
  47.         PagedResults.CurrentPageIndex = pageIndex-1; //because this is indexed based
  48.  
  49.         //after the PagedDataSource class is in place we can then
  50.         //feed this into the repeater itself
  51.         repeater1.DataSource = PagedResults;
  52.         repeater1.DataBind(); //repeater does not bind natively
  53.  
  54.         //configure paging number - Google Style
  55.         //to do this we dynamically create X amount of links based on the total
  56.         //results and the PageSize - we can’t create these buttons here as
  57.         //events will only run if added in design time or page_init/page_load
  58.         Control OuterPanel = FindControlRecursive(repeater1, “placeLinks”);
  59.         OuterPanel.Controls.Add(innerPlaceHolder);
  60.     }
  61.  
  62.     protected void SqlDataSource1_Selected(object sender, SqlDataSourceStatusEventArgs e)
  63.     {
  64.         //variable used to create X amount of buttons
  65.         Session[“totalResults”] = e.AffectedRows;
  66.     }
  67.  
  68.     protected void PagingLink_Command(object sender, CommandEventArgs c)
  69.     {
  70.         Session[“pageNumber”] = c.CommandArgument.ToString();
  71.         Page_with_Repeater();
  72.     }
  73.  
  74.     private Control FindControlRecursive(Control root, string id) { } //removed for clarity
  75.  
  76. }

All the important paging related code is encapsulated in the Page_with_Repeater() function, it’s all commented so I won’t repeat myself here. As far as what the code does, well it displays 5 rows of data at a time from the underlying datasource (in this case SqlDataSource1) in a repeater. LinkButtons are dynamically created and then added to the repeater to display page numbers as links to allow the user to select a specific result page. Often interfaces allow the user to select a specific page (as in this example) and to use previous and next buttons for working his or her way through data, on that note a good example of using buttons for repeater paging is given on the 4guysfromrolla.com website. 

The corresponding .aspx markup for the c# code is very simple and contains a repeater (named ‘repeater1′) with an embedded panel (named ‘placeLinks’) and an SqlDataSource (named ‘SqlDataSource1′) which specifies an event hander for the ’selected’ event in order for us to create the correct amount of paging links.

Incidentally you may notice in the C# code above that I have used a custom function called FindControlRecursive to enable me to add the dynamically created placeholder (which contains all the page number linkbuttons) to the statically created panel within the repeater. This is a handy function I came across recently and which I often use in conjunction with repeater controls (and many other controls too). It accepts a root control and an id of the target control to look for. It works in a similar way to the standard FindControl method except it searches all controls (including child controls) in a control tree hierachy whereas FindControl will only search the specific control you pass it without examining any child controls.

That’s it - paging with a repeater using an SqlDataSource is implemented. As you can see it is not too difficult. If you have any questions please feel free to ask.  

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • YahooMyWeb
  • Reddit
  • Simpy
  • De.lirio.us
  • StumbleUpon
  • Technorati
  • Netscape
  • Spurl
  • blogmarks
  • blinkbits
  • SphereIt
  • Slashdot
  • Ma.gnolia

Microsoft Certified Technology Specialist (MCTS)

Thursday, August 9th, 2007

Booked myself in for one of the two exams required for the MCTS - .NET Framework 2.0 Web Applications certification yesterday. The exam I’m going for is the Microsoft .NET Framework 2.0 - Web-Based Client Development exam (code 70-528). I’m booked in for mid September to do it with New Horizons Ireland at a cost of €140. New Horizons seem to be the only Dublin based exam center available.

The exam focuses on using ASP.Net 2.0 to build highly dynamic, secure and scalable web applications and questions a developers knowledge of such things as standard & custom controls, data access via ADO.Net, web parts, membership, state management, mobile web applications, management & deployment of web apps and much much more. To help me prepare I got the training kit book by Glenn Johnson and Tony Northrup covering this specific exam and reviewed two very highly rated Wrox ASP.Net books which I bought last year. Additionally the fact I’ve been doing most of this stuff in my daily 9 to 5 for a good while now means I’m feeling pretty confident. In fact I anticipate much more difficulty with the other exam required for this certification - the Microsoft .NET Framework 2.0 - Application Development Foundation exam (code 70-536).

Incidentally I’m also considering going for another certification. It’s the ISEB Foundation Certificate in Software Testing. I think everyone would agree that software testing and software development are very complementary skills. Not sure where this can be done though and if classroom training is required, ideally I would just like to get stuck into a good book for a few weeks.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • YahooMyWeb
  • Reddit
  • Simpy
  • De.lirio.us
  • StumbleUpon
  • Technorati
  • Netscape
  • Spurl
  • blogmarks
  • blinkbits
  • SphereIt
  • Slashdot
  • Ma.gnolia

Ajax example - staff directory search with PHP & C# ASP.Net

Sunday, August 5th, 2007

Ajax in a nutshell is a set of technologies which allow for partial page updates without requiring the whole page to refresh after communication with the server. Usually when a visitor is on a webpage and clicks a link or a button the whole page is reloaded (and the browser window goes white) before the user can see the updated page back, however with Ajax the user could see the specific results of the link/button click almost immediately as only the relevant section of the page is updated. What Ajax (the frontend) updates the page with is usually based on what it passes to the server (backend).

Ajax uses Asynchronous communication to allow this type of update to a page. Asynchronous communication in this context basically means that the loading of data/information (for example results from an SQL Query) for display in a specific section of the web page does not interfere with the normal loading of the web page and thus the page will not freeze or go white as is normally the case. The idea with Ajax is to give the end user a much better experience. This better experience comes from increased responsiveness/speed and usability.

Have a look at the following two pages (which open in new windows) which provide the user with the ability to lookup contact details for staff of a dummy company called HollyWood MovieStars Ltd.

Standard search interfaceAjax enabled search interface (have a sneak at the source if you want)
TIP - Search for one of the vowels first.

The first page is a standard search interface where you enter in your query, press search and watch as the whole page posts back, reloads and gives you back your search results. The second page is an Ajax enabled search interface which returns results almost immediately as soon as you start typing your query - without requiring a whole page reload. I know which one would make me the happier end user.

In this post I’ll present a step by step example of how to use Ajax to create a much more responsive and user friendly interface than is possible with the regular request and wait protocol we are all so familiar with. The interface I’m actually going to put together is the Ajax enabled one shown above. As you can see it basically allows a user to quickly look up the contact details of a member of staff by sub string searching on their name information which is stored in a database somewhere. I’m tagging this one as a staff directory search but it could just as easily be used to find details for club members, clients etc. The important thing is the underlying concepts and not what it’s actually used for. 

The actual Ajax code which communicates with the server is written in Javascript and thus the frontend of this interface will just be a standard webpage (.html extension) with a mixture of Javascript/HTML and a touch of CSS/DHTML too. For the backend - which does the actual SQL query database lookup based on what the Ajax frontend passes to it and returns results I will provide summary code in both PHP and C# ASP.Net. You could actually use the exact same PHP or C# ASP.Net code to run both a standard click and wait search interface and an Ajax enabled one (if you set the form method to GET on the standard search page) so there is definitely nothing special about the backend in this case and thus summary code and summary explainations are all that’s needed for the backend in this case.

XMLHttpRequest
Let’s begin with the object that makes everything Ajax possible. The XMLHttpRequest javascript based object is the actual mechanism that allows independent asynchronous communication between client and server. Without it Ajax would not exist. As you can see from the XMLHttpRequest Wikipedia page the object has a number of methods (actions) and properties (values) available to it. The most important methods include Open() and Send(), while the most important properties are onreadystatechange, readyState, status and ResponseText at least for this example anyhow. OK let’s see some code and then I’ll offer a line or two on the above methods and properties as we come across them. The function below is your bread and butter Ajax client to server communication code…

  1.  function getText(urlToCall, functionToCallBack, divToUpdate)
  2. {
  3.    
  4.     var XMLHttpRequestObject = false;
  5.  
  6.     //will exist in navigator, firefox & safari
  7.     if (window.XMLHttpRequest)
  8.     {
  9.           XMLHttpRequestObject = new XMLHttpRequest();
  10.     } 
  11.     //will exist in explorer
  12.     else if (window.ActiveXObject)
  13.     {
  14.          XMLHttpRequestObject = new
  15.          ActiveXObject(“Microsoft.XMLHTTP”);
  16.     }
  17.  
  18.     //if object was created successfully
  19.     if(XMLHttpRequestObject)
  20.     {
  21.             XMLHttpRequestObject.open(“GET”, urlToCall);
  22.             XMLHttpRequestObject.send(null);
  23.  
  24.             XMLHttpRequestObject.onreadystatechange = function()
  25.            {
  26.                  if (XMLHttpRequestObject.readyState == 4 && XMLHttpRequestObject.status == 200)
  27.                 {
  28.                     functionToCallBack(XMLHttpRequestObject.responseText, divToUpdate);
  29.                     delete XMLHttpRequestObject;
  30.                     XMLHttpRequestObject = null;
  31.                 }
  32.            }
  33.     } //end if object created
  34.  
  35. } //end of function
  36.  

Lines 6 through 16 are what actually creates a new instance of a XMLHttpRequest object for use later in the function. How the Javascript creates the object depends on what the current browser is. This is required as Internet Explorer creates the underlying object differently than most other browsers.  

Line 19 simply checks if the earlier logic to create the XMLHttpRequest object was successful, and if this is the case it calls the open() method of the object. This is a very important method and is used to inform the XMLHttpRequest object of the location of the backend script (urlToCall) to call and communicate with. It also specifies the mode of communication, the most common modes of communication are POST and GET. How you pass data to the backend script depends on what option you select as the mode of communication, in this case this is set to GET - meaning we will pass data (whatever the searcher types into the search box) via query strings embedded into the url of the backend script (urlToCall) which we want to communicate with. It is important to note that no actual communication with the server has begun - open() simply specifies information about an async request which is about to happen, thus in this way the use of the word open is perhaps misleading.

Line 22 is what actually kicks things off, it does this by sending the request to the backend script as specified by the urlToCall parameter. Referring back to our XMLHttpRequest Wikipedia page we notice that the send method can take one parameter called content. This parameter is used to specify the data to send to the backend script if we set our mode of communication to POST. The backend script would then by able to access this data in a standard way such as $_POST[’data’] in PHP or Request.Form[”data”] in C# ASP.Net. Since we are passing data via query params (GET mode) attached to the filename specified by urlToCall we only need to pass a value of null.

Next up we see the onreadystate change property which calls an anonymous function everytime the state of the request changes. In the function both readyState and status are checked to make sure the request is a) complete and b) successful. The two magic numbers here are ‘4′ (readyState) meaning the the request is fully complete and ‘200′ (status) meaning the communication between client and server was successful.

Line 28 is just a standard Javascript function call to the function specified by functionToCallBack. The call passes in the text that was returned from the backend script via the XMLHttpRequest objects’ ResponseText property as well as the id of the div (or span/p etc.) element to update with the response. It is of course possible to handle the ResponseText right there in the anonymous function, however this is not a good idea as each Ajax application will be handling responses differently so it’s better to keep the getText function clear of any hardcoding and use specific embedded callback functions for each different page. Doing this will mean you can use the same getText function again and again in lots of different Ajax interfaces without modification.

Finally for the getText function lines 29 and 30 use good programming practice and dispose of now unneeded resources.

Incidentally the getText function I’ve used here is actually a slightly modified version of a function which is part of a very simple (but more often than not sufficient) Ajax framework which was originally included with an Ajax book I read called Ajax Bible written by a guy called by Steven Holzner. I thoroughly recommend the book to anyone wanting to get aquainted with Ajax and what it can do. As for the framework, it can be downloaded from http://www.akamarketing.com/scripts/ajaxutility.js, you will notice that getText is one of four functions available. By the way don’t be scared off by the word ‘framework’, a framework in the context of development is basically just a load of pre written code for you to use as a base, it’s nothing more and nothing less.

Displaying the response in the browser
The getText function as outlined above looked after the async client & server communication side of things and called another function on line 28 (commonly referred to as the callback function) when everything was done. The whole purpose of this callback function is to handle and display the response of the aforementioned communication. Let’s have a look at this very simple function now…

  1. //this function gets called when results are ready from the server side
  2. function callbackfunction(text, divToUpdate)
  3. {
  4.     //handle response in here, in this case we are just outputting it
  5.      document.getElementById(divToUpdate).innerHTML = text;
  6. }

I’m sure anyone used to fiddling with the DOM and/or DHTML can see what’s going on here. This code is basically instructing the browser to update the div as indicated by divToUpdate with the response outputted by the backend script and passed in via the parameter text.

Getting the ball rolling with user driven events 
You’ve seen how the callback function gets called from within the getText function, but how does the getText function get called in the first place? Good Question! The getText function gets called by tying it to some user driven event such as a button click, mouse move or keypress. You can see from the Ajax enabled search interface (the one we’re trying to make) that there isn’t a button in sight so we won’t be attaching a call to the getText function to an onClick event. Instead to enable getText to get called with each and every single keypress (and hence provide search results very quickly) in the query textbox we are using the onkeyup event. Here is the code we need.

  1. <input id=“query” onkeyup=“getText(’ajax-backend.php?query=’+document.getElementById(’query’).value+'’,callbackfunction, ’searchResults’)” name=“query” type=“text” /> 

Notice that in this case the backend is PHP driven, also notice how we are embedding the search query into the backend filename. In this case the HTML element which we want to update with the server response has the id ’searchResults’. This means that a div, span, p or some other HTML element which exposes the InnerHTML property and has an id of ’searchResults’ must be present on the page or a Javascript error will occur. At this stage the client side frontend of our staff search interface is complete, you can get the full source by opening the Ajax enabled search interface page and selecting View >> Source from the toolbar. You may notice that the getText function is included in the frontend via an external JS file.

All that’s left to do now is to complete the backend code. The backend code is pretty standard issue stuff. Your basically checking for a query string param called ‘query’ and if it’s found your executing an SQL query (with the query string embedded) against a DB and simply outputting the results. The backend summary code is first given for ajax-backend.aspx (C# ASP.Net) and is then given for ajax-backend.php (PHP).

ajax-backend.aspx

  1. <!–Page Language=“C#”–>
  2. <!–Import Namespace=“System.Data.SqlClient”–>
  3. <script>
  4.     protected void Page_Load(object sender, EventArgs e)
  5.     {
  6.         //if something is in the query param do a LIKE search
  7.         //against the staff directory database and return results if any
  8.         if (Request.QueryString[“query”] != null)
  9.         {
  10.             string query = Server.HtmlEncode(Request.QueryString[“query”].Replace(“‘”,“‘’”));
  11.             SqlConnection connection = new SqlConnection(“connection string in here”);
  12.             SqlCommand command = new SqlCommand();
  13.             SqlDataReader reader;
  14.  
  15.             command.Connection = connection;
  16.             command.CommandText = “select * from staff_directory where firstname like ‘%” + query + “%’ or…”;
  17.  
  18.             connection.Open();
  19.             reader = command.ExecuteReader();
  20.  
  21.             int count = 0;
  22.             while (reader.Read())
  23.             {
  24.                 Response.Write(
  25. <tr>
  26. <td>reader[0].ToString()….. etc. etc.”);
  27.                 count++;
  28.             }
  29.  
  30.             if (count == 0)
  31.             {
  32.                 Response.Write(“Sorry no results were found for your search”);
  33.             }
  34.         }
  35.     }
  36. </script>
  37.  
  38. <!– Stripped out all other output as frontend is handled by ajax-frontend.html –>

ajax-backend.php

  1. <!–r–>if(isset($_GET[“query”]) && $_GET[“query”] != “”)
  2. {
  3.  
  4.  $dbcon = mysql_connect(“localhost”,“username”,“password”);
  5.  
  6.  if (!$dbcon)
  7.  {
  8.    die(‘Not connected : ‘ . mysql_error());
  9.  }
  10.  
  11.  $db_selected = mysql_select_db(‘DB’, $dbcon);
  12.  if (!$db_selected)
  13.  {
  14.    die (‘Can\’t use foo : ‘ . mysql_error());
  15.  }
  16.   
  17.  //setup a query
  18.  $query = “select * from staff_directory where firstname like ‘%” . $_GET[“query”] . “%’ or lastname like ‘%” . $_GET[“query”] . “%’ or firstname + ‘ ‘ + lastname like ‘%”. $_GET[“query”] . “%’”;
  19.  
  20.  //execute the query
  21.  $get_results = mysql_query($query);
  22.  if (!$db_selected)
  23.  {
  24.    die (‘Query Error : ‘ . mysql_error());
  25.  }
  26.  
  27.  if(mysql_num_rows($get_results)>0)
  28.  {
  29.   $counter=0;
  30.   while($row = mysql_fetch_array($get_results))
  31.   {
  32.    $counter++;
  33.    echo “<strong>NAME</strong>: “ . $row[0] . ” “ . $row[1] . ” <strong>PHONE:</strong> “ . $row[2] . ” <strong>EMAIL:</strong> “ . $row[3] . ” <strong>SEX:</strong> “ . $row[4] . “”;
  34.   } 
  35.  }
  36.  else
  37.  {
  38.   echo “Sorry no results were found for your search”;
  39.  }
  40.  
  41. }
  42. ?> 

Neither the C# ASP.Net or PHP code given above is complete or production ready, both code samples do however provide you with a very good idea of what needs to go on from the backend point of view. Remember anything that you Response.Write() or echo out on the backend page will be returned to the client via the XMLHttpResponse objects’ ResponseText property.

Well that’s really it, with both the frontend and backend elements of an example Ajax interface covered you should now be able to implement something similar to suit your own needs, if not I hope I have at least provided you with a good basis for further research and remember if your stuck on anything please drop me a comment. In fact even if your not stuck please drop me a comment as I’d love to get your feedback on this post.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • Digg
  • Furl
  • YahooMyWeb
  • Reddit
  • Simpy
  • De.lirio.us
  • StumbleUpon
  • Technorati
  • Netscape
  • Spurl
  • blogmarks
  • blinkbits
  • SphereIt
  • Slashdot
  • Ma.gnolia