When you think ASP, think...
Recent Articles
All Articles
ASP.NET Articles
ASPFAQs.com
Message Board
Related Web Technologies
User Tips!
Coding Tips
Search

Sections:
Book Reviews
Sample Chapters
Commonly Asked Message Board Questions
JavaScript Tutorials
MSDN Communities Hub
Official Docs
Security
Stump the SQL Guru!
Web Hosts
XML
Information:
Advertise
Feedback
Author an Article

ASP ASP.NET ASP FAQs Message Board Feedback
 
Print this Page!
Published: Wednesday, October 7, 2009

Creating a Filtering User Interface With jQuery In a Web Forms Application: Part 1

By Scott Mitchell


Introduction


jQuery is a lightweight, cross-browser JavaScript library designed to ease JavaScript's most common tasks, including inspecting and manipulating the Document Object Model (DOM) and making out of band HTTP requests to support AJAX functionality. In plain English, jQuery makes it easy to perform client-side tasks like adding or removing attributes or CSS classes to elements in the DOM, or showing or hiding elements on the page in response to a user action (such as clicking a button). jQuery is used by many popular Web 2.0 sites to help implement rich, interactive features. jQuery can certainly be used in an ASP.NET application, although integrating client-side script into a Web Forms application can sometimes be a bit trying. JavaScript development fits more naturally with ASP.NET MVC applications; in fact, the ASP.NET MVC framework includes the jQuery libraries. What's more, Microsoft has announced that jQuery will be included with Visual Studio 2010 and beyond.

I recently had the opportunity to use jQuery in a intranet-based line of business Web Forms application. This application has a number of reporting screens that use a GridView control to display the report results. Users often want to filter the results to get a more concise snapshop of the data they are interested in, and to that end many of these reports include a filtering user interface, which is a series of drop-downs, checkboxes, and textboxes, through which they can apply various filtering criteria.

Some of these filtering user interfaces have gotten so expansive that nearly an entire screen of real estate is chewed up by the filtering user interface alone! We needed a way to collapse this filtering interface and only expand it upon user request. Using jQuery, some CSS, and a few lines of JavaScript, I was able to implement an entirely client-side approach to expanding and collapsing the filtering interface. This article, Part 1, walks through the nuts and bolts of this functionality. The upcoming Part 2 looks at how to extend the collapsible filtering user interface functionality so that it remembers the collapsed/expanded state on a user-by-user basis. Read on to learn more!

- continued -

A Quick jQuery Primer


jQuery is a JavaScript library that simplifies common JavaScript tasks, such as DOM manipulation and client-side event handling. jQuery allows developers to access elements in the HTML DOM through the use of selectors. The syntax takes a little getting used to, but selectors allow for a quick and easy way to access and modify an HTML element. For instance, given an HTML element with the id of filterUI, you can access this element using:

$('#filterUI')

To hide this element, simply use the hide() function like so:

$('#filterUI').hide();

To show it, use the show() function:

$('#filterUI').show();

There's also a toggle() function that shows the element if it's currently hidden, and hides it if it's currently displayed. There are functions to add or remove attributes or CSS classes, and functions to perform animations, like having an element appear or disappear through a fade in or fade out, or a slide in or slide out.

jQuery also makes it a cinch to create client-side event handlers. Imagine that you have a page with two elements with ids A and B. When someone clicks A you want to show B if it is hidden or hide it if it is visible. To accomplish this all you need to do is create an event handler for A's click event in which you call the toggle() function on B. Here's the jQuery code to accomplish this:

$('#A').click(function() {
   $('#B').toggle();
});

The above JavaScript defines an event handler for A's client-side click event. The event handler contains one line of code: $('#B').toggle();

A similar syntax is used to execute JavaScript code once the web page has loaded. The document object's ready event fires once the page and jQuery library has been loaded by the browser. To execute code at this point, write JavaScript like the following:

$(document).ready(function() {
   // Star up code goes here...
}

That start up code can include both statements - such as $('#A').show() - as well as event handler definitions, like $('#A').click(function() { ... }.

The Impetus For A Collapsible Filtering User Interface


The application available for download at the end of this article includes a simple and straightforward data-driven report with a filtering interface. Specifically, the page uses a GridView to display the results from a SqlDataSource control that queries the Products table in the Northwind database. The page also contains some filtering controls:
  • A DropDownList that lets the user narrow down the listed products to those that belong to a single category,
  • A CheckBox from which the user can specify whether to include discontinued products in the report, and
  • A TextBox into which the user can type in a minimum price - only those products with a price greater than or equal to the minimum price are returned.
The following screen shot shows this filtering user interface and the resulting GridView.

The filtering interface allows users to winnow down the report results.

As the number of filtering options grows, the filtering interface will start to consume more and more screen space. To help reclaim this space, we can collapse the filtering interface and not show it unless the user explicitly expands it. This is especially useful if the majority of users who view this report do so without filtering. For these users it greatly cleans up the screen and commits more real estate to the report data. Those users that need to filter the report are just a single click away from seeing the filtering interface.

The remainder of this article explores how to implement a collapsible filtering interface in a Web Forms application using jQuery (although the concepts would work equally as well in an ASP.NET MVC application). Please note that this article does not discuss how to display and filter database results. For more information on such topics check out my article series on Accessing and Updating Data in ASP.NET.

What About The CollapsiblePanel Control?
The ASP.NET AJAX Control Toolkit includes a CollapsiblePanel control which provides the functionality we desire, namely a way to expand and collapse a region on the screen using client-side script. The benefit of using the ASP.NET AJAX Control Toolkit is that you don't have to write any JavaScript - just add the extender to your page, set a few properties, and you're done.

I considered using the AJAX Control Toolkit for my project, but decided to pass for a couple of reasons. For starters, the other developers on the team were already familiar with JavaScript and jQuery and were comfortable writing client-side script, yet they had no experience with the AJAX Control Toolkit. And there are future plans for adding features that are right up jQuery's alley, so now seemed as good a time as any to integrate jQuery into the site. Also, while not relevant to this project, jQuery can be used in ASP.NET 1.x applications, whereas the ASP.NET AJAX framework and the ASP.NET AJAX Control Toolkit cannot. But the clinching drive was neither technological nor business-driven, but rather personal: I've used the CollapsiblePanel in previous projects, but I had not used jQuery in a real-world project and wanted to get some experience. Call it the opposite of the Not Invented Here effect.

The Filtering User Interface's HTML


The filtering user interface is composed of four Web controls - a DropDownList, CheckBox, TextBox, and Button - all arranged within a two-column HTML <table>. The <table> is encased inside a <div> element whose id attribute is set to filterUI. There's another <div> with an id of filterUItitle, which displays the "Filter Product Listing" title. This <div> appears immediately before the filterUI <div> and is assigned the CSS class expandIcon, which we'll examine momentarily. These two <div>s (filterUItitle and filterUI) are enclosed within a <div> whose class attribute is set to filterBox.

The following snippet shows the markup for these three <div>s.

<div class="filterBox">
   <div id="filterUItitle" class="expandIcon">Filter Product Listing</div>
   <div id="filterUI">
      <table>
         <tr>
            <td class="filterHeader">
               Category:
            </td>
            <td>
               <asp:DropDownList ID="ddlCategories" ...>
               </asp:DropDownList>               
            </td>
         </tr>
         ...
      </table>
   </div>
</div>

The Filtering User Interface's CSS Classes


There are three CSS classes used by the filtering interface. The filterBox CSS class, which is assigned to the outermost <div>, affects the appearance of the entire filtering user interface. Specifically, it sets the background color to a light pale yellow, puts a black, 1 pixel-wide border around the filtering user interface, and adds some padding.

.filterBox
{
   border: solid 1px black;
   padding: 5px;
   background-color: #ffd;
   margin-bottom: 15px;
}

The other two CSS classes used here are named expandIcon and collapseIcon. These CSS classes are used on the filterUItitle <div>. These CSS classes are used primarily to add an appropriate expand or collapse icon to the filterUItitle element. As their names imply, the expandIcon class renders an "expand" image in the filterUItitle bar, whereas the collapseIcon class shows a "collapse" image (see the screen shot below to see the "expand" and "collapse" images). When the filtering user interface is collapsed, the filterUItitle <div>'s CSS class should be set to expandIcon so that the "expand" icon is shown; conversely, when the filtering interface is expanded, the CSS class should be set to collapseIcon.

I have it so that the filtering interface is collapsed by default, which is why the HTML above has the filterUItitle <div>'s class attribute set to expandIcon. We will use jQuery to change the CSS class from expandIcon to collapseIcon when expanding the filtering user interface, and from collapseIcon to expandIcon when collapsing the filtering user interface.

The expandIcon and collapseIcon CSS class definitions follow:

.expandIcon
{
   background-image: url(Images/expand.jpg);
   background-position: left;
   background-repeat: no-repeat;
   padding-left: 18px;
   cursor: pointer;
}

.collapseIcon
{
   background-image: url(Images/collapse.jpg);
   background-repeat: no-repeat;   
   background-position: left;
   cursor: pointer;
   padding-left: 18px;
}

The following screen shot shows the filtering user interface with the above HTML and CSS applied. Right now the filtering user interface is expanded, yet the "expand" image is displayed. We will fix that in a moment by using jQuery to hide the filterUI <div> when the document loads.

The filtering user interface with the markup and CSS classes applied.

Collapsing The Filtering User Interface When The Page Loads


After the browser completes downloading the user interface we want to collapse the filterUI <div>. This can be accomplished by creating a document ready event handler and calling the hide() function like so:

<script type="text/javascript">
   $(document).ready(function() {
      $('#filterUI').hide();
   });
</script>

With that, when the page is loaded the filtering user interface is collapsed. That was easy!

The filtering user interface is collapsed, by default.

Toggling The Collapsed/Expanded State When Clicking The filterUItitle <div>


While our current incarnation certainly collapses the filtering user interface, there's no way to expand it. We need a client-side click event handler for the filterUItitle <div>, in which the filterUI <div> is displayed (if hidden) or hidden (if displayed). Moreover, the filterUItitle's CSS class needs to be changed from expandIcon to collapseIcon, or vice-a-versa.

jQuery makes implementing such functionality a walk in the park. Adding the four highlighted lines of JavaScript to the document ready event handler is all it takes:

<script type="text/javascript">
   $(document).ready(function() {
      $('#filterUI').hide();

      $('#filterUItitle').click(function() {
         $('#filterUI').slideToggle(400);
         $('#filterUItitle').toggleClass('expandIcon');
         $('#filterUItitle').toggleClass('collapseIcon');
      });

   });
</script>

The slideToggle() function animates the display (or hiding) of the filtering user interface over by sliding it from the top down over 400 milliseconds. The toggleClass(className) function adds className to the element if it is not present, and removes it if it is present. Therefore, the two toggleClass lines of code remove the expandIcon or collapseIcon class from the filterUItitle <div>, while adding the other one.

That's all there is to it! To see this code in action, be sure to download the demo available at the end of this article.

Looking Forward...


One downside of the functionality we have in place now is that whenever the page is visited the filtering user interface will be collapsed. That means that if the user expands the filtering interface, leaves the page, and then comes back later, she'll have to re-expand the filtering interface. Similarly, any sort of postback that occurs on the page - such as clicking the Filter button or sorting the grid - will cause the filtering interface to collapse. While an UpdatePanel could be used to ensure that the filtering interface maintains its collapsed/expanded state across postbacks, the fact remains that the user's collapsed/expanded selection will certainly not be remembered across different page requests.

The good news is that with a little bit of AJAXy goodness we can have it so that the collapsed/expanded state is remembered across the user's session. We'll explore how to add such functionality in the upcoming Part 2 of this article!

Until then... Happy Programming!

>> Read Part 2 >>

  • By Scott Mitchell


    Attachments:

  • Download the code for this article
  • Further Reading


  • jQuery.com: jQuery homepage and download site
  • jQuery Tutorials
  • AJAX Control Toolkit CollapsiblePanel Control
  • Creating a Filtering User Interface With jQuery In a Web Forms Application: Part 2


  • ASP.NET [1.x] [2.0] | ASPMessageboard.com | ASPFAQs.com | Advertise | Feedback | Author an Article