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:
Let's start with the last item.
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.
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.
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:
Go ahead and try the form!
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:
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.)
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!
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);
this
ObjectSuppose 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:
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.