Events and Event Handlers

Events

Our websites have so far been pretty passive: they present material for the user to read or look at, but nothing more interactive. Now that we know about forms, our code can process input from the user and dynamically modify the page. We just need a few more concepts to make a page that is interactive:

  • Events: these are things the user does, such as clicking on something or submitting a form.
  • Event Handlers: these are functions that we define and that the browser will invoke when a particular event occurs.
  • Getting values out of forms when we want to know what the user entered.

Let's start with the last item.

Getting Form Values

jQuery has a convenient method for retrieving the value of an input, the .val() method. The selector should be anything that selects the input, such as its id. Here's a form with three inputs:

The IDs of the three inputs are customer1, pizza_kind1, and num_slices1.

Fill out the form and use the following execution box to retrieve the values:


The .val() method works just like other jQuery methods: the wrapper function selects the element you want to operate on, and the method does the work. Here, it pulls the value out of the input.

Note that values from forms are always strings, even if the form says that the input is type number. If you want it to be a number, you have to use parseInt or parseFloat, just as we did with values returned by prompt.

Now that we know how to use forms, we'll never need prompt again.

Units Conversion

Let's build a slightly useful form: one that will allow the user to do metric conversions. They will enter a number of pounds, and the form will compute the conversion to kilograms. (One kilogram is 2.2 pounds.)

We'll define two functions to do the work:

  • pounds2kilograms, which takes an argument of pounds (a number) and converts it to kilograms, returning the number of kilograms. This is a generic function that might be useful in a wide variety of problems.
  • doConversion, which pulls the numberof pounds out of the form, converts it to a number, invokes the first function to get the number of kilograms, and then inserts the answer, formatted with 1 decimal place, into the span above.

Here's the source code for the form we will use:

<form>
  <p><label for="pounds1">Pounds</label>
    <input type="text" name="pounds" id="pounds1">
  <p><button type="button" id="convert1">Convert</button>
  <p><span id="kg1"></span> kilograms</p>
</form>

Here's the live form. The button doesn't do anything yet.

kilograms

Here's the code to execute:


At this point, we almost have a working form. What we need is to set things up so that instead of the execution box invoking the doConversion function, the user can cause it be be invoked by clicking on the button.

To re-phrase that in the terminology of this reading, we want the doConversion function to be an event handler for the event of the user clicking on the button.

jQuery has a convenient method of attaching a function to some element in the document so that the function gets invoked when the element is clicked on. That method is the .click() method. Here's how we will do it:

$("#convert1").click(doConversion);

Notice, by the way, the lack of a pair of empty parentheses after the function name, doConversion. That's because we are not invoking the function here. Instead, we are handing it to jQuery to be attached to the web page as an event handler. To use our earlier metaphor, we are passing the function as a machine, like a blender or meat grinder, for someone else to use, but we are not pressing the on button right here.

Here's our revised code:



Let's see the code in action. Here's a duplicate form, but now the IDs end in 2 instead of 1:

kilograms

Go ahead and try the form!

Events and Event Handlers

The preceding section showed a particular example of a event handler (the doConversion function). It will be invoked to handle a "click" event on that particular button. Let's step back and discuss more generally what these things are.

An event is something that happens in the browser, often initiated by the user, but not always. Some examples:

  • an element is clicked on
  • an element is moused over
  • the HTML is loaded and the DOM is ready (we saw this in the reading on the DOM)
  • some data finishes loading from the server
  • a timer has expired
  • some keys are pressed on the keyboard

There are others, but these are more than enough for our purposes.

An event handler is just a function that will be invoked when a particular event occurs. In other words, it's not a special kind of function, it's a particular use for a function. That said, for our purposes, an event handler will be a function that takes no arguments and returns no values, because that's how it will be invoked. (That's not strictly true, but it is close enough for now.)

Hide and Show

Our forms don't have to have lots of inputs; they can consist of just a button or two. Here is a form with just two buttons. Try them, and watch the picture below!

Harry Potter
Fig1: Harry Potter

Here's the code. You'll notice that there are two simple functions that hide/show the element whose ID is fig1. You're welcome to try them from the JS console; there's nothing special about them. Then, we have two lines of JQ that attach those functions to the two buttons.

function hideFigure1() {
    $("#fig1").hide();
}

function showFigure1() {
    $("#fig1").show();
}

$("#hide1").click(hideFigure1);
$("#show1").click(showFigure1);

The this Object

Suppose we had a long list of items, and we want to allow the user to click on any one of them to make them disappear. Here's an example of the behavior we want:

  1. Harry
  2. Ron
  3. Hermione
  4. Neville
  5. Luna
  6. Ginny
  7. Draco
  8. Crabbe
  9. Goyle
  10. Cho
  11. Cedric

Clearly, we could give each of these 11 items a different ID, we could define 11 functions that are all pretty much the same except for the ID of the thing they are hiding, and attach each function to one list item. Something like this. I've written the functions on one line both for brevity and to make it easier to compare their code.

function hideItem1() { $("#elt1").hide(); }
function hideItem2() { $("#elt2").hide(); }
function hideItem3() { $("#elt3").hide(); }
...

$("#elt1").click(hideItem1);
$("#elt2").click(hideItem2);
$("#elt3").click(hideItem3);
...

Code like that is tedious and boring, and it doesn't scale well. If we had a list of the 50 states in the US, or 196 countries in the world, the code is excessively tedious and boring. There must be a better way, and there is.

The idea is to attach the same function to each item in the list, so we only have to define one function. The function, however, has to figure out which item to hide. In this case, the answer is the one that was clicked on.

Any time an element is clicked on, the special variable this contains the element. So, in the example above, if you click on the first element in the list (Harry), the hideItems1 function runs, but this contains that LI. Similarly for all the others.

Here's our revised code:

function hideItem() { $(this).hide(); }

$("#char_list li").click(hideItem);

Try it!

One important part of the code is the selector, "#char_list li", which matches all 11 LI elements in that list in one, easy but powerful bit of code.

The key piece of code, of course, is the following:

$(this).hide();

That code uses this as the selector, taking that element on the page and wrapping it up with all the jQuery methods, including the .hide() method. Before, we've always seen the selector contain a string literal, describing the element or elements to be operated on. Here, we have, essentially, a magic variable whose value is just the thing we want.

The technique of using the this variable is fairly complex and advanced, and we won't need it often, but it's good to know about.

© Wellesley College Computer Science Staff. This work is licensed under a Creative Commons License. Date Modified: Sunday, 28-Aug-2016 13:05:58 EDT