-
Notifications
You must be signed in to change notification settings - Fork 0
04 Add Tasks to the List
We need to wire up our form to add items to the task list.
"If you wish to make an apple pie from scratch, you must first invent the universe."
Listen to your friend Carl Sagan. He's a cool dude.
To setup an event handler on a form, you must first have the form. The jQuery
function, usually invoked as the $
function, gets elements from the DOM. It accepts a CSS-style selector and returns all matches1, much like document.querySelectorAll
.2
jQuery's implementation has a number of differences. Most significant is that what it returns is not simply an array of DOM elements; it's a special array-like collection of jQuery objects that contain the actual DOM elements. Wrapping them in jQuery objects allows us to call an assortment of jQuery functions to traverse and manipulate them. We can also call these functions on the collection itself, and they will be applied to all elements in the collection.
In this case, we have only one element to grab: The form.
$('form#new_task')
To handle the form submission, we set up an onclick
event handler. We do this rather than adding an onclick
event handler to the submit button, because it works with other means of submitting the form as well (such as pressing the enter
key).
In jQuery, we can add event handlers by calling the on
method of a jQuery collection or object.
.on( events [, selector ] [, data ], handler )
For now, we'll ignore the optional selector
and data
parameters. We need to pass it a string naming the event we're handling (submit
), and a function to act as the handler. We can pass it in as an anonymous function, or as a reference to a named function.
For now, pass it as an anonymous function. As with traditional event handlers, it will receive an event as an argument, but this time it's jQuery's normalized Event
object that deals with some cross-platform inconsistencies for us.
Attach the event handler after our variable and property declarations in the Listly
function. As usual with submit
handlers, we want to prevent the default behavior. The jQuery Event
object includes the familiar preventDefault
function.
js/listly.js
6 self.tasks = [];
7
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 });
Ultimately our event handler will do a few things. For now, let's just add a new list item (<li>
) to the task list in the DOM. First, we need to get the value of the text field. Use a debugger to see what value this
holds in our event handler, since are in jQuery territory.
js/listly.js
6 self.tasks = [];
7
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 debugger;
11 });
Inspect this
in the console, and you'll find that this
is set to the actual form
element, not a jQueryized version. So we can use traditional DOM properties to get the text field value.
Don't forget to remove the debugger
line from your code!
var task_name = this.task_name.value;
If we want to get fully onboard the jQuery train, jQuery objects have a val()
function that will give us what we want. We can simply wrap $this.task_name
in the $
function and call val()
.
var task_name = $(this.task_name).val();
Do it whichever way you prefer. In my code snippets here, I'm going to use the jQuery function for consistency's sake.
js/listly.js
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 var task_name = $(this.task_name).val();
11 });
jQuery includes several handy functions for adding elements to the DOM. One that fits our needs in this case is append
.
.append( content [, content ] )
The append
function adds content, specified by the parameter we pass, at the end of the matched elements. (By matched elements, we mean whatever elements are contained in the jQuery object on which we call the function.)
Notice that it can accept multiple parameters. We can include as many pieces of content as we like, and jQuery will append them all.
One of the best things about this and many other DOM-related functions in jQuery is that it accepts a variety of formats for its parameter(s). We can pass in an actual DOM element to be appended; we can pass in an element or elements wrapped in a jQuery object; or we can pass in a string of HTML.
It's very easy for us to build an html string for the <li>
that includes our task name.
'<li class="list-group-item">' + task_name + '</li>'
Append that string to the <ol>
, which we gave an id of tasks
.
js/listly.js
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 var task_name = $(this.task_name).val();
11
12 $('#tasks').append('<li class="list-group-item">' + task_name + '</li>');
13 });
Try it out in your browser!
It works, but the user experience could be improved. Focus the cursor back inside the text field and clear its value. jQuery's val
function can not only get the value of a field, but also set it. We can also call jQuery's focus
function to place the cursor back inside the text field.
js/listly.js
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 var task_name = $(this.task_name).val();
11
12 $('#tasks').append('<li class="list-group-item">' + task_name + '</li>');
13 $(this.task_name).val('');
14 $(this.task_name).focus();
15 });
These jQuery functions also return the jQuery object that they act upon, so we can chain the function calls.
js/listly.js
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 var task_name = $(this.task_name).val();
11
12 $('#tasks').append('<li class="list-group-item">' + task_name + '</li>');
13 $(this.task_name).val('').focus();
14 });
Try it out.
All told, your JavaScript should now look something like this:
js/listly.js
1 function Listly() {
2
3 function Listly() {
4 var self = this;
5
6 self.tasks = [];
7
8 $('form#new_task').on('submit', function(ev) {
9 ev.preventDefault();
10 var task_name = $(this.task_name).val();
11
12 $('#tasks').append('<li class="list-group-item">' + task_name + '</li>');
13 $(this.task_name).val('').focus();
14 });
15 }
16
17 return Listly;
18 }
19
20 var listly = new Listly();
1 It can also accept a string of HTML and build a DOM element from it! ↩
2 When jQuery first arrived on the scene, querySelectorAll
didn't yet exist, and the jQuery 1.x branch continues to support browsers that lack the built-in function. ↩