jQuery Goodness in a DotNet World

jQuery is one of the most popular JavaScript frameworks. It shields the programmer from the idiosyncrasies in the way that each browser implements the language: it makes life easier by doing all the routine chores and takes the pain out of AJAX. It also introduces a 'Wow' factor to browser-based applications.

Now we have Web 2.0 applications, it is not enough to simply have moderately interactive web pages that post back every time the user does anything on the page. The post back model served us well for many years, but sites like Google and Facebook among others have raised the bar and users expect web sites that are as interactive as the traditional app installed locally.

JavaScript allows you to add client side processing, but for most of us, delving too deep into the guts of JavaScript is just a recipe for disaster. AJAX makes it easier for JavaScript code to send requests and receive responses back from the Server. This allows a web page to send a request for a subset of the page and update only the pieces that are affected instead of posting everything back and updating the entire page. This alone makes the page feel more responsive. Since the first A in AJAX stands for asynchronous, the page is not frozen while waiting on the request as would be the case with a traditional post back.

jQuery shields us from one of the biggest hurdles with using AJAX, the J. JavaScript is not the easiest language to learn and use. There is often limited editor or debugger support, and there are also still browser compatibility issues. Shocking that after all this time, we still have to worry about browser nuances, but we do.

jQuery solves these problems! How?

jQuery becomes a layer on top of JavaScript shielding us from some of the uglier sides of writing JavaScript code. Yes, we still are writing JavaScript code, but it does not feel as arcane as traditional JavaScript. The jQuery libraries will detect the browser, OS, etc and accommodate the differences so that we do not have to worry so much about the browser compatibility issues.

It is also now very easy to get intellisense for jQuery by simply referencing the correct distribution from the Microsoft CDN.

This levels the playing field so that everyone can create more engaging feature rich and interactive web applications.

Solving Common Problems Easily

There are many jQuery plug-ins available to solve a wide array of problems. There are controls built using jQuery that are as interactive as a windows control and no more difficult to use than a standard web control, but jQuery can also be used to provide very simple solutions to some very common problems.

Zebra Stripes

It looks nice to stripe the rows in a table to make them easier to read. We often jump through hoops to make this happen. GridViews even add two style sheets to support this behavior. While this is not a bad solution, jQuery provides an even better solution.

Add a snippet of code similar to the code shown below and the odd rows in every table will be styled with the oddRow class. If you want to target to specific tables, simply change the selector.

1116-img4.jpg

Resize Elements

When formatting a page, we often need to make similar items the same size. You may want the header and the footer to be the same width or the content and sidebar the same height. You may also want to make every menu item the same size. Here are some useful functions to do just that.

This first function will make all of the items identified by the group the size of the tallest item. I add a parameter to specify a max height. If the tallest item is taller than the max height specified, then all items will be resized to the maxHeight even the items that are already taller.

This function will go through and make every item identified in the group have the height specified regardless of what the original heights were.

These next two functions behave the same except with the width dimension.

These functions will work their magic with a snippet similar to this:

1116-clip_image002.jpg

Indicating required fields

We often need to indicate that certain fields are required. This may take the form of a red as part of the label. With jQuery, you can easily add such functionality with a single line like this:

Or you could also add functionality by attaching logic to the blur event for the selected controls:

Add this little bit of jQuery logic to the header of a master page and you get this functionality across all pages. All you have to do is style the label and the input control with the correct style sheet classes.

Making the Impractical Practical

Sometimes the tasks are more complicated, and we are given challenges that cannot reasonably be solved without a framework like jQuery.

I was recently presented with the challenge of supporting paging through the records of a data grid by scrolling. The client wanted to be able to scroll through the records and have new records pull in when the user scrolled instead of requiring the user to explicitly use the paging controls.

My first reaction was that this could not be done in the timelines provided. My second reaction was that this may be a good place for some jQuery magic.

jQuery provides a scroll event that gets raised when the user scrolls. We can wire up this event and pull new data as the user scrolls. This is pretty wild magic. It is also not really paging, more like chunking through the data, but the client was pretty impressed.

To make this magic work, we will have two components, the JavaScript code, and a web service. The JavaScript code will look similar to this:

There are a couple of things to note here. We specify the web service where we will get data in the URL property. Any parameters needed by the web service will be passed in the Data property. The parameters need to be formatted like they would be passed on a query string to a web page request.

The success and error properties define functions that are called to deal with the result of the web service call. The success function will be called when the web service call finishes successfully. The error function will be called if there is an error making the call. The success function accepts three parameters, data, textStatus, XMLHttpRequest. We are only interested the first parameter which will be the result of the web service call formatted based on the dataType property. For our purposes, we want html to be returned that we can drop right onto the page. Other cases may warrant a JSON string to be returned that can de-serialized and processed by the success function. The error function also accepts three parameters, request, textStatus, errorThrown. Most of the time, we will only be interested in the second parameter. This will be the error message coming back from the web service.

The success function has one additional interesting piece of logic. We are explicitly checking to see if the string returned includes the expression “END OF RECORDS”. I place this in the web service response when there are no more records to be retrieved. As long as the response does not include this sentinel value, we add the returned string to the end of the scrollable region. When this sentinel value is returned, we unbind the scroll event. This will prevent the scroll event from firing.

There are additional events that can be wired up as needed, such as complete which gets raised after success or error regardless of the state of the web service call, but success and error will generally be all you need to wire up.

Our actual web service will be like any web method or page method that you write. Simply make sure that you return the return value in the same format that the success function expects.

Creating the ‘Wow’ Factor!

Jquery is full of animation tricks that create a ‘wow’ factor, and the auto paging can add a little wow as well, but nothing screams wow quiet like being able to move the controls around on a screen. This can take the form of being able to move a modal popup around on the screen, or allowing the user to rearrange the components on the page, or something a bit more engaging like allowing the user to sort items or relate items by dragging them around.

We have all seen pages where you selected items from a multi item select box to map a many to many relationship or a one to many relationship such as employees to a manager, members to a group, rules to a workflow etc. Imagine instead being able to drag the selected items and dropping them on the entity that you want to associate them with. Such functionality has long been common with traditional windows applications. Until recently, such magic was elusive for their web cousins. Not anymore. Here we will use the extensive plugin jQuery UI.

Among other things, jQuery UI provides interaction components like draggable, droppable, and sortable. We will use these components to build an association control. The intention here is to show an item and a collection of items to be associated to it. We will then allow the user to drab items from this collection and drop them on the original item to make the association. Once the association has been made, we would also like to allow the user to drag the dropped controls around to sort them. This is a very engaging way to perform an otherwise mundane task. Let’s start with the html markup.

There are a couple of items to note here. First our data list expects to be bound to a list of items with properties called Id and Name. The ui-widget-header class comes from the jquery ui theming. The draggable class defines the div as a drag able item.

The drop zone is even easier to mark up than the drag able item.

The drop class defines the div as a drop zone and will allow it to receive dragged items.

The script is what associates the classes to the jQuery functionality. There is nothing special about the class names, but reasonable names do help us keep everything straight. Now let’s turn our attention to the JavaScript.

The calls to the jQuery objects associate the style sheet classes to the jQuery behavior.

The drop function specifies in the droppable method adds the element to the drop zone. We call the append method to add the item to the drag able div.

For sortable, we will only worry about it setting a class for the place holder. The sortable component exposes several events that many people will wire up to post the updates back to the server. This works, but I find this to be potentially overly chatty. This also has the disadvantage of committing changes before the user is finished. I have opted for a different approach.

Instead, let’s set a hidden variable with the final order of the selected items before posting back. Once we post back, we can then query this hidden variable to determine the end result of what the user has done. A little bit of JavaScript code needs to be added to populate this hidden variable field.

Back on the server side, we can access the contents of this hidden variable with code like this:

We can then loop through the items and retrieve the IDs for the items that the user selected in the order that they were applied.

1116-img6.jpg

Conclusion

AJAX makes web applications as rich and interactive as a traditional windows application. jQuery straightens and flattens  the learning curve for introducing exciting new functionality. We also benefit from having a rich intuitive API that removes some of the pain of having to use JavaScript. jQuery simplifies the syntax and semantic nuances of JavaScript and shields us from the browser idiosyncrasies.