Mats Lycken development

.NET and web related blog posts

NAVIGATION - SEARCH

jQuery part 2 - Event handling

jQuery makes event handling in javascript very easy and extremely handy to perform all kinds of different things in the UI.

The great thing about the event handling is that you can bind to events to almost anything, this makes things like creating hover effects over tables and creating clickable divs a breeze. And since you use the jQuery css style selectors to specify which elements you want to bind the event to, you can bind the event to many elements with one line of code!

I’ll start out by showing you how to bind the click event.

Click events

sample 1 - click events.htm

 

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   2: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   3: <html xmlns="http://www.w3.org/1999/xhtml" >
   4: <head>
   5:     <title>jQuery sample 1 - click events</title>
   6:     <script type="text/javascript" src="jquery-1.2.6.min.js"></script>
   7: </head>
   8: <body>
   9:     <div>
  10:         <a id="bindLink" href="#">Bound link 1</a>
  11:     </div>
  12:     <ul>
  13:         You can use the same code to bind to different types of elements!
  14:         <li><button class="bind2">a button</button></li>
  15:         <li><a class="bind2" href="#">a link</a></li>
  16:     </ul>
  17:     <div id="bindDiv">
  18:         You can also bind to other types of elements
  19:     </div>
  20:     <script type="text/javascript">
  21:         // this is how you make code run once 
  22:         // the complete document has been loaded
  23:         $(document).ready(function() {
  24:            $("#bindLink").bind("click", function() {
  25:                 alert("You clicked the link!");
  26:            }); 
  27:            $(".bind2").bind("click", function() {
  28:                 alert("You clicked the element with tagName: " + this.tagName);
  29:            }); 
  30:            $("#bindDiv").bind("click", function() {
  31:                 $(this).append("<br />Clicked me....");
  32:            });            
  33:         });
  34:     </script>
  35: </body>
  36: </html>

In this sample I use the method

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

This makes sure that the DOM tree has been fully loaded before the code in the function runs. This is great place to put code that should run once in the page.

To bind an event you use the bind(event, function) method. The event is specified as a string without the ‘on’ in the beginning and all lower case characters.

Some of the available events are:

  • click
  • dblclick
  • mouseenter
  • mouseleave
  • mousemove
  • etc… (check out the events section on http://docs.jquery.com)

To bind the click event to an element with an id of ‘bindLink’ I write the following:

$("#bindLink").bind("click", function() {
     alert("You clicked the link!");
}); 

 

You can create a separate function but an inline anonymous function works just as well.

If I want to access the element that was clicked inside the function I can do so via the ‘this’ keyword:

$(".bind2").bind("click", function() {
     alert("You clicked the element with tagName: " + this.tagName);
}); 

Inside of the function ‘this’ will refer to the element that was clicked. One thing to note is that it refers to the DOM element, not the jQuery object. If I want to have a jQuery object wrapped around the element I need to write $(this).

$("#bindDiv").bind("click", function() {
     $(this).append("<br />Clicked me....");
}); 

Here we use the .append(html) method will add the html string to the end of the contents of the element. If you wanted to insert content before the content you could have used .prepend(html). There are also the methods .before(html)  and .after(html) that will add content before and after the DOM element itself.

Mouse over and out

sample 2 - mouse enter and leave.htm

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   2: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   3: <html xmlns="http://www.w3.org/1999/xhtml" >
   4: <head>
   5:     <title>jQuery sample 2 - mouse enter and leave</title>
   6:     <script type="text/javascript" src="jquery-1.2.6.min.js"></script>
   7:     <style type="text/css">
   8:         .hoverDiv { font-size: 2em; padding: 1em; width: 23em; text-align: center; }
   9:         .hovering { background-color: #faebeb;color: #fa0000; }
  10:     </style>
  11: </head>
  12: <body>
  13:     <div class="hoverDiv">
  14:         1. Move the mouse over me to make cool stuff happen. :)
  15:     </div>
  16:     <div class="hoverDiv">
  17:         2. Move the mouse over me to make cool stuff happen. :)
  18:     </div>
  19:     <div class="hoverDiv">
  20:         3. Move the mouse over me to make cool stuff happen. :)
  21:     </div>
  22:     <script type="text/javascript">
  23:         $(document).ready(function() {
  24:             $(".hoverDiv")
  25:                 .bind("mouseenter", function() {
  26:                     $(this).addClass("hovering");
  27:                 })
  28:                 .bind("mouseleave", function() {
  29:                     $(this).removeClass("hovering");
  30:                 })
  31:                 .bind("click", function() {
  32:                     alert("My text is: " + $(this).text());
  33:                 });
  34:         });
  35:     </script>
  36: </body>
  37: </html>

In this sample I’ve used the mouseenter and mouseleave events to create a hover effect. The list of divs all have a specific class so that I can bind to them all at once.

I then chain together multiple bind methods to make sure we handle enter, leave and click events. The click event just tells us what text the div we clicked contains.

To create the hover effect I use the handy methods addClass and removeClass. These are great to create these kinds of effects. There is also a toggleClass that will alternately add and remove the class.

Special click event – Toggling

If you want to switch between two different states of an element there is an alternative to bind that is called toggle(function1, function2).

It will alternately call function1 and function2 when you click the element. Here’s a sample where we turn on and off list elements.

sample 3 - toggle event.htm

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   2: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   3: <html xmlns="http://www.w3.org/1999/xhtml" >
   4: <head>
   5:     <title>jQuery sample 3 - toggle event</title>
   6:     <script type="text/javascript" src="jquery-1.2.6.min.js"></script>
   7:     <style type="text/css">
   8:         li { width: 30px; border: solid 1px black; text-align: center; }
   9:         .on { background-color: Yellow; font-weight: bold; }
  10:     </style>
  11: </head>
  12: <body>
  13:     <ul>
  14:         Click to turn on/off
  15:         <li>Off</li>
  16:         <li>Off</li>
  17:         <li>Off</li>
  18:         <li>Off</li>
  19:     </ul>
  20:     <script type="text/javascript">
  21:         $(document).ready(function() {
  22:             $("ul li").toggle(function() {
  23:                 $(this).text("On").addClass("on");
  24:             }, function() {
  25:                 $(this).text("Off").removeClass("on");
  26:             });            
  27:         });
  28:     </script>
  29: </body>
  30: </html>

Here we alternately change the text, and look, of the list elements between on and off.

Creating a table with selectable rows

We’ll finish off the examples of event handling by creating a table where the user has the ability to select rows. This could for instance be used to create a simple online file manager.

sample 4 - selecting table rows.htm

 

 

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
   2: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   3: <html xmlns="http://www.w3.org/1999/xhtml" >
   4: <head>
   5:     <title>jQuery sample 4 - selecting table rows</title>
   6:     <script type="text/javascript" src="jquery-1.2.6.min.js"></script>
   7:     <style type="text/css">
   8:         table, td, th { border: solid 1px black; border-collapse: collapse; 
   9:                         padding: 4px; }
  10:         .selected td { background-color: Yellow; }
  11:         .hovering td { background-color: #ebebeb; }
  12:     </style>
  13: </head>
  14: <body>
  15:     <table id="files">    
  16:         <colgroup>
  17:             <col style="width: 300px;" />
  18:             <col style="width: 100px; text-align: right;" />
  19:             <col style="width: 100px; text-align: right;" />
  20:         </colgroup>
  21:         <tr><th>Filename</th><th>File size</th><th>Last modified</th></tr>
  22:         <tr><td>image1.jpg</td><td>56 KB</td><td>2005-12-01</td></tr>
  23:         <tr><td>image3.gif</td><td>114 KB</td><td>2005-12-05</td></tr>
  24:         <tr><td>flowers.jpg</td><td>23 KB</td><td>2005-08-12</td></tr>
  25:         <tr><td>happy people.png</td><td>94 KB</td><td>2005-06-23</td></tr>
  26:         <tr><td>stuff.jpg</td><td>312 KB</td><td>2005-03-12</td></tr>
  27:     </table>
  28:     <ol id="selected">
  29:         You have selected the following files
  30:     </ol>
  31:     <script type="text/javascript">
  32:         $(document).ready(function() {
  33:             $("#files tr:has(td)")
  34:                 .bind("click", function() {
  35:                     $(this).toggleClass("selected");
  36:                     UpdateSelectedList();
  37:                 })
  38:                 .bind("mouseenter", function() {
  39:                     $(this).addClass("hovering");
  40:                 })
  41:                 .bind("mouseleave", function() {
  42:                     $(this).removeClass("hovering");
  43:                 });
  44:         });        
  45:         function UpdateSelectedList()
  46:         {
  47:             $("#selected li").remove();
  48:             $("#files .selected").each(function () {
  49:                 $("#selected").append(CreateFileItem($(this)));
  50:             });
  51:         }        
  52:         function CreateFileItem(element)
  53:         {
  54:             return "<li>" + element.find("td:first").text() + "</li>";
  55:         }        
  56:     </script>
  57: </body>
  58: </html>

Here we add a simple table with a few rows. The table could be the output of a repeater control that lists the contents of a directory. Beneath the table we have an ordered list where we display the files that we have selected.

When you look at it in the browser it looks quite complex, but as you see the javascript code is really simple.

If you take a look at the selector we use a filter for the table rows. tr:has(td) will only select the table rows that has td-tags as children. This will filter away the first row that is our header row.

We then use the click event to toggle the class “selected” which will update the background color. It then calls the function UpdateSelectedList(); which updates the list of selected files.

function UpdateSelectedList()
{
    $("#selected li").remove();
    $("#files .selected").each(function () {
        $("#selected").append(CreateFileItem($(this)));
    });
}   

 

We begin by selecting all list items and remove them. Then we select all table rows that has the css class “selected” and run the .each(function) function on them. This is the same as foreach() in .NET. For every selected table row we append a new list item to list.

function CreateFileItem(element)
{
    return "<li>" + element.find("td:first").text() + "</li>";
}      

To get the name of the selected file we use the filter :first which selects only the first matched element and the get the name with .text().

And that’s pretty much it.  The only other code we have is the mouseenter and mouseleave events to get a nice hover effect over the table rows.

This is beauty of jQuery, with really simple code you can create really impressive results that seem much more complex than they are. And since jQuery handles all cross browser issues it will work in all modern browsers.

If you compare this solution with the classic ASP.NET solution, which would be performing a postback on every click, you must agree that this is much more elegant and not that much harder to code.

As usual I recommend downloading the samples and play around with them. Also you should check out http://docs.jquery.com, especially the events section.

jQuery samples - part 2.zip (19,70 kb)

Comments (2) -

A nice and interesting post! Thanks for the read. A suggestion: Since you have a lot of examples which could be run by the browser, why don't you also show how they look when run? Att the DOM elements necessary and add the scripts so that the visitor, e.g. me, can click and drag and test whatever the scripts are supposed to do?

Reply

Great article. I would also recommend you show the demo on your site as well. We understand the code by would like to see it in action before we try it out.

Thanks

Reply

Add comment