Forms are a basic part of the web. Thanks to sites like Google, Amazon, and Facebook, there is hardly a day where a person can get on the web without interacting with at least one form. Be it to run a search, buy something, or simply login to check their messages, anybody that has used the Internet in the past 10 years has used a form at least once in their life.
So, if it is practically mandatory that you use a form while surfing the web, why not make them pretty? Fortunately, that is not the intent of this tutorial. If it were, then this website would be intended for designers, not programmers, and we can't be having any of that going on here.
Anyway, to get started, it would be a good idea to first know what an event is. To that point, if you think you already know what you're doing and are just looking to learn more about events in JavaScript, I'd recommend you read a very detailed article from Quirksmode on Introduction to Events. In fact, after you have taken some time to get familiarized with the basics of events in JavaScript, I recommend you give that article a read anyway. You will learn more about JavaScript from that site alone than just about anywhere else on the Internet.
Well, that's enough talk, back to the point. In JavaScript, an event is something that gets called whenever a user interacts with your
website. If you scroll a little then the onscroll
event gets fired. Click on something? Then the onclick
event gets fired. Moving your mouse around a bit much? Then you're probably triggering several mouse events;
provided the page you're viewing makes use of any of them you may even be seeing things happen as you move the mouse (perhaps you're
hovering over something which opened a navigation menu?).
I think you got the point by now, so (if you didn't look at any of the previous links) how do you make use of events? There are two ways. One is simple; the other is still simple but a little less novice-friendly. So we'll start with the friendly one: just use an HTML attribute.
<input type="button" name="a_button" value="Click Me" onClick="window.alert('You just clicked me!');">
I'm assuming you already know basic HTML, so you should know how to put that into a HTML page, load it in your browser, and click the button to see what happens.
But that looks really simple doesn't it? Too simple perhaps? Nah, it's just another attribute on the input
tag, not very
unlike the other attributes. Now, you should be aware of something here. There are very few events that are actually limited in terms of
what tags they can be applied to. For instance, the onload
event can (basically) only be applied to a body
tag (or from within a script
tag, it would be referred to as
window.onload
). The rest can, in general, be applied to any tag within an HTML document. The above example would work just
as well if I had used a span
tag instead. But that is beside the point for now.
Let's say you want something more exciting to happen when you click the button than just telling you something you already know. Let's say you want to select a set of elements to display depending on the state of a group of radio buttons. More specifically (and less practically), you can use a couple of radio buttons to present a user with the option of logging in, or registering.
To start, you're going to want to make a .js file to put all of the JavaScript included in this tutorial into and include it in your
HTML page, or simply paste it in a script
tag inside the head
of your document (there is an example page at the
end of this tutorial if you want to skip the complicated copy/paste stuff). And here is the first bit of JavaScript you'll want. It is
called when you change the state of the radio buttons and simply changes the display of a couple of tags to present the user with different options.
/* Since we only want one view open at a time, when we change views, * we need to make sure that only one view remains open. To do that, we must * hide all of the views, and then go back and "re-open" the one we want displayed. */ function hideAll(){ document.getElementById('register_options').style.display = 'none'; document.getElementById('login_options').style.display = 'none'; } function changeLoginOptions(button, set_id){ /* Make sure the selected radio button was checked, we don't want to go * off showing something when it isn't even what we selected */ if(button.checked){ hideAll(); document.getElementById(set_id).style.display = 'block'; } }
And the accompanying HTML (which FF2 isn't too fond of):
<form method="post" action="./"> <table> <tr> <td>Username: </td> <td><input type="text" name="username" value=""></td> </tr> <tr> <td></td> <td> <label><input type="radio" name="login_set" value="1" onClick="changeLoginOptions(this, 'login_options');" checked="checked"> Login</label> <label><input type="radio" name="login_set" value="2" onClick="changeLoginOptions(this, 'register_options');"> Register</label> </td> </tr> <tr id="login_options" valign="top"> <td>Password: </td> <td> <input type="password" name="pass" value=""><br> <input type="submit" name="login" value="Login"> </td> </tr> <tr id="register_options" style="display:none;"> <td></td> <td><input type="submit" name="register" value="Register"></td> </tr> </table> </form>
The main things to pay attention to in the above block of HTML are the use of onclick
attributes on the input
tags and the id
/style
attributes on the tr
tags. Specifically observe how those relate to the
hideAll
() function in the JavaScript. Also note the use of 'this
' in the call to changeLoginOptions
().
In this case, this
refers to the tag that the onclick
attribute applies to. It allows you to let the function
know what object (or tag) called the function so you can do fancy things like checking the attributes of the given object to determine
what you want the function to do.
You can play around with that for a bit until you feel as though you've got the hang of it. Once you do, you should ask the question of how exactly we are going to handle what page loads after the user hits one of the submit buttons. One option (the better option) would be to handle that on the server side, but that wouldn't be any fun now would it? After all, sometimes you want to evaluate the contents of a form before it's actually submitted (again, a job better suited for the server side). Specifically, you might want to check to make sure a username was entered before trying to register them, and then redirect them to a registration page instead of the login page.
To do that, we're going to make use of the onsubmit
event. With it we can determine whether or not the form is actually submitted by returning true
(go ahead and submit the
form) or false
(don't submit) from within the event handler. This is useful when validating form conditions before submitting
to the server, and can be used to save the user a page refresh (again, check the data on the server side anyway).
function validateForm(form){ /* Get some of the form data. * Note: I do not recommend using this method, it was just easier for the sake of example. */ var login_set = form.elements['login_set'], username = form.elements['username'].value.replace(/^\s+|\s+$/g, ''), password = form.elements['pass'].value, current_state = 0; // Figure out which button is checked for(x=0; x < login_set.length; x++){ if(login_set[x].checked){ current_state = login_set[x].value; break; } } // current_state still equals initial value, don't know what to do error if(current_state == 0){ window.alert('No radio button selected.'); return false; } // No username entered, universal error if(username == ''){ window.alert('Please enter a username.'); // Trigger the focus event on the username field so the user can start typing after the alert. form.elements['username'].focus(); return false; } // Username is good, see if we should go to the registration page if(current_state == 2){ /* Insert redirect to registration page here, i.e: window.location.href = './register.php?username='+username; */ window.alert('Redirect to login page for user: '+username); return false; } // No password entered while attempting to login, error if(current_state == 1 && password == ''){ window.alert('Please enter a password.'); // Trigger the focus event on the password field so the user can start typing after the alert. form.elements['pass'].focus(); return false; } // Nothing wrong, let the form continue go to where the action attribute specifies return true; }
The other thing we'll need to change is the form
tag from our previous HTML code:
<form method="post" action="./" onSubmit="return validateForm(this);">
You should notice all that changed there is the addition of an onsubmit
attribute. The really special thing to notice is
the return
statement before the call to validateForm
(). This allows us to use the result that is returned from
the validateForm
() to control whether or not the form is actually submitted. In fact, links operate in exactly the same way.
If the onclick
event of an a
tag returns false, the link won't be followed (i.e. you won't be sent to a new page).
And that about wraps it up for how to use events in JavaScript by setting them as HTML attributes. Since it is the easiest way to set events, I would recommend it for any beginner. However, it is also "politically incorrect" to do so. A lot of people frown on the idea of setting JavaScript events inside of HTML like that and they do so for good reason. It is hard to maintain and can result in some very ugly markup. As such, it is a much better idea to get references to your tags by making use of the DOM and setting the events inside of JavaScript itself. The following two examples illustrate both 1) The complete tutorial as illustrated above, and 2) The tutorial above without the use of HTML attributes for setting the events.
Examples:
Via HTML Attributes
Via JavaScript
Disclaimer: Remember, this isn't a design site, so the examples are quite bland.