JavaScript I – Day 10
Geekwise Academy
Instructors:
Corey Shuman
Aaron Lurz
Slack Channel:
https://geekwise-js1.slack.com
Github:
https://github.com/coreyshuman/Geekwise-JavaScript-I
Lesson plans:
http://coreyshuman.github.io/Geekwise-JavaScript-I/html/
· Review Day 9 DOM and assignment
· Handling Events
o Event Listeners
o Working with Forms
o Submit Event
o
Working with radio buttons and check boxes
In JavaScript, Event listeners are how we can react to user interaction on the page. For instance, alert something to a user when they try and delete an element, or run an arbitrary JavaScript function when a user clicks a button.
The DOM has built in methods that allow for registering "handlers" for a given "event", like click or mouse over.
Let's start by creating a simple html page with a button. We'll assign an event handler to the button.
<button id="alert">
Alert something
</button>
Now that we have a button we can add a click
handler for, let's actually add the listener. We will use
the element.addEventListener(event, handler)
function where event is a string for a named event, and
the handler is a function to call when the event happens. In this way, the
function is referred to as a callback
.
Try it: Add the button markup, and write some JS that will select the button, and then use the button to add an event listener.
var
button
=document
.getElementById("alert");
button
.addEventListener("click",function
()
{
alert("hello world");
console
.log(this); //what is the context to our callback function?
});
Now, if you've added the button markup and run that JavaScript,
you should now be able to click on the button and see an alert. Notice the console.log
there? What is the this
of the
function?
In callbacks, it's usually the case that the context
will be the node element itself.
Let's make this a little more dynamic.
Add an attribute to your button called rel="..."
<button id="alert" rel="This is some text">
Alert something
</button>
Use that new rel
attribute as the content of our alert. Since we know
that the context of our function is going to be the node itself, we can use all
of our node related functions on this object.
Try it: Use the this
inside your callback to get the attribute value and alert
that instead of the hard coded text.
var
button
=document
.getElementById("alert");
button
.addEventListener("click",function
()
{
alert(this.getAttribute("rel"));
});
Use what we've learned to add p
nodes
with a rel
attribute. Then use the addEventListener
to handle clicks on the p
tags.
Alert the rel
attributes
for each p
that is clicked on.
//loop our movie array and create one li for each movie,
//with the title as the text
movieObjs = [
{title: "Star Wars"},
{title: "Inception"},
{title: "The Matrix"}
];
for
(var
i
=0;
i
<movieObjs
.length
;i
++){
var
movie
=movieObjs
[i
];
var
a
=document
.createElement("p");
a
.textContent
=movie.title;
a
.setAttribute("rel",movie.title
);
a
.setAttribute("style","color:red;");
a
.addEventListener("click",function
()
{
alert(this.getAttribute("rel"));
});
document.body
.appendChild(a
);
}
The above modification will add a rel
attribute to
our p
nodes that will track the movie title, and the new event listener will listen
for click
events and run the specified callback which will alert
the rel
attribute.
There are many more event types you can have element's listen for, and many that are used specifically with forms. We'll talk about those next...
Forms in HTML are a perfect way to collect information from someone interacting with your webpage. Until now, we've used prompts as a way of collecting data, but prompts are clunky which makes a form a much more attractive alternative. Form usages vary widely based on the type of information you're collecting, and which form elements you decide to work with.
Start with a simple text input that will allow us to input a movie title.
<
form name
="newMovieForm"id
="newMovieForm">
<
input type
="text"name
="movieTitle"id
="movieTitle"/>
<
input type
="submit"value
="Add Movie"/>
</
form
>
Notice, we've added id's to our form and our input. This is going to make it easy to work the form fields in JavaScript.
Also, notice that our form tag lacks an action or method attribute you may be familiar with. This is because we aren't actually going to be submitting this form in a traditional way. We'll be using JavaScript to work with the form, meaning there won't be a traditional submit needed.
So, just like we added a click
event to our tags in the previous exercise, there are
other events we can listen for and react to with JavaScript. One of these is
the submit
event of
an HTML form.
This works like you would probably expect. We get a reference to our form, add a submit event listener, then write a callback function to handle processing our form.
To start with, our goal will be to alert
the movie title entered in the form when we click the
submit button. To do this, we need to know how to get the value
from a form field. We use the value
property for this.
document
.getElementById("movieTitle").value
;
Enter a value in the field and then run the above code in the console. The result should be the value you entered in the field.
Now that we know how to get the value of a form field, let's add an event handler that will alert the value of the movie title field when the form is submitted.
var
form
=document
.getElementById("newMovieForm");
form
.addEventListener("submit",function
()
{
var
movie
=document
.getElementById("movieTitle").value
;
alert(
movie
);
});
Now, enter a value in your form field, and click submit. What happens? What result did you get? What happened after you dismissed the alert?
You should have seen your form was submitted. Well, that's not very useful, since as soon as the form is submitted, all the JavaScript we were executing will be refreshed, and everything starts over from scratch. Wouldn't it be great if we could somehow stop that page refresh from happening?
This is where the event
object
becomes really useful. The event listener callback that we've been working with
actually receives one argument. We've not used it thus far, but when the
callback is run, it's passed the event
object as
an argument.
The event object contains properties and functions related to the event that occurred, a submit event in this case.
It also contains functions that allow us to alter how the
event continues after our callback function has run. One particularly useful is
the evt.preventDefault()
function.
The preventDefault()
function does exactly what it says, it prevents the
default behavior from occurring. That means is we are working with a submit
event, the preventDefault
function would prevent the submit
from
happening, making our callback function the only way to work with this form, as
it will no longer submit. Let's try it!
//notice the evt argument now being passed to the event listener callback
var
form
=document
.getElementById("newMovieForm");
form
.addEventListener("submit",function
(
evt
){
var
movie
=document
.getElementById("movieTitle").value
;
alert(
movie
);
evt
.preventDefault();
});
So now we get our movie title alerted, but the form no longer submits. Success!
Radio buttons let you select one option from a group items. The name attribute on a group of radio buttons is always the same.
Add a "genre" radio group with a few options.
<
form name
="newMovieForm"id
="newMovieForm">
<
input type
="text"name
="movieTitle"id
="movieTitle"/>
<
div id
="genre">
<
input type
="radio"name
="genre"value
="comedy"/>
comedy
<br
/>
<
input type
="radio"name
="genre"value
="drama"/>
drama
<br
/>
<
input type
="radio"name
="genre"value
="horror"/>
horror
</
div
>
<
input type
="submit"value
="Add Movie"/>
</
form
>
We can't use getElementById
to get our radio inputs, but the DOM does give us some
other methods we can use to work with them.
document.getElementsByName(...)
can be used in order to select an element by its name
attribute, which is perfect for radio buttons, since they always have the same
name.
var
genreInputs
=document
.getElementsByName("genre");
console
.log(genreInputs
);
What does genreInputs
look like
in the console? An array! Does it have a length? Yes! We can loop it!
In order to find out which option from a radio group was
selected, we need to look at the checked
property
of each radio.
Try it: Loop the genre inputs and find which element is
checked by looking for the checked
property
on each element.
var
genre
;
for
(var
i
=0;
i
<genreInputs
.length
;i
++){
var
genreInput
=genreInputs
[i
];
if
(
genreInput
.checked
){
genre
=genreInput
.value
;
}
}
console
.log(genre
);
The loop above will interrogate each radio element and see if it's checked. If it is, it sets the genre variable equal to the current radio elements value.
One important thing to remember is that radio elements are only meant to return one value.
i. Hint: there are ways to have events for many items be handled by a single function instead of writing an event handler for each and every tag. We will cover this next week.