To-Do Chrome Extension Part 3 – Make it Work
This is part three of the series on making a to-do extension for Google Chrome.
- Part 1 – Project Setup
- Part 2 – Browser Action Popup
- Part 3 – Make it Work
In this post we are going to finish the browser action popup to a state where it is fully functional. That means being able to add, remove, edit and complete tasks. We will also apply some styling so our eyes won’t burn to death each time we look at it.
Bind event handlers
We have a lot of elements laying in our extension, that does nothing. We need to hook these up to an event handler. In JavaScript there are two ways you can add an event handler to an element. First, and most common, is by using the addEventListener method (target.addEventListener('click', handler, false)) or using jQuery ($(target).click(handler)). These are great because they make the HTML code very clean from JavaScript and element attributes. The other way is through element attributes, e.g. <a onclick="handler()">. In a website this easily gets messy in the markup and makes it harder to maintain. On the other hand, in extensions we write a lot more JavaScript than in a normal webpage and would rather choose to have clean and maintainable script files. This is why I will attach all event handlers through element attributes in our extension.
We only need four handlers in our popup – the checkbox (onchange), task textbox (onkeyup), remove button (onclick) and the add task textbox (onkeyup), which makes our code look like this:
<div class="item" jsselect="$this" jsvalues="id:id">
<input type="checkbox" onchange="view.changeCompleted(this.parentNode.id, !!this.value)" class="completed" checked="checked" jsvalues="checked:completed" />
<span class="title" onkeyup="view.changeTitle(this.parentNode.id, this.innerText)" contenteditable="true" jscontent="title"></span>
<button class="remove" onclick="view.removeTask(this.parentNode.id)" title="Remove Task">Remove</button>
</div>
</div>
<input type="text" id="add" onkeyup="view.newTask(event)" placeholder="Write task and press enter..." />
You likely notice that I have included some parameters to each event handler. These help to identify which task I am changing. E.g. this.parentNode.id gets the parent element’s id attribute (where we store the task’s id).
Implementing the handlers
We will be keep all our handlers in the view object that we created in the previous post. The first handler is the one to add a task, called newTask. It will fire each time you type in the textbox but we only want save a new task when the user presses the enter key, which is why we need an if statement to check for that. The rest is simply adding the new task with our TaskRepository and resetting the textbox. We will also change the init function a bit since last post.
init: function() {
this.textbox = document.getElementById('add');
this.renderView();
},
newTask: function(e) {
if (e != null && e.which == 13 && this.textbox.value != "") { // enter key
db.create({
title: this.textbox.value,
completed: false,
created: new Date()
});
this.textbox.value = '';
view.renderView();
}
},
There are three handlers left to write, but they are very self explanatory and won’t need a closer description as they will merely be using methods of TaskRepository. Following is the code for changeTitle, changeCompleted and removeTask:
db.getById(id).title = title;
db.save();
},
changeCompleted: function(id, completed) {
db.getById(id).completed = completed;
db.save();
},
removeTask: function(id) {
db.remove({ id: id });
view.renderView();
return;
},
Styling the popup
If you run the extension in its current state you will see that all functionality works as expected, but like I said in the previous post, it looks horrible and is hard to use. I have prepared some CSS styles for it, but as this post isn’t about CSS I won’t be getting into details about it. If you want to have a look at the CSS code, see the ZIP file at the bottom.
Before and after styling the popup:
Round up
In only three posts we managed to create a fully functional to-do manager for Google Chrome. This shows how easy it is to develop for Chrome with HTML 5 and JavaScript.
Our extension still doesn’t fulfill all our requirements, though. We still need to implement an options page and a task counter in the icon. That’s the subject for the next post.
I have “compiled” the extension to an installable .crx file in case you want to run it and see how it works. Personally I’m already using this extension for my to-do lists.
Source code is, like always, available in a link below.
