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.

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 do nothing. We need to hook these up to event handlers. 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 or jQuery’s bind method. Those 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 websites this easily gets messy and makes it harder to maintain. On the other hand, in extensions we write a lot more JavaScript than in a normal web page 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.

Update: Chrome has tighten their security policy so inline event attributes in HTML is not allowed anymore. I recommend looking at KnockoutJS as an alternative. More info on Content Security Policy.

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 id="results">  
    <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.

textbox: null,

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:

changeTitle: function(id, title) {
    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:

Before styling  image

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.

Source code is, like always, available in a link below.

Downloads

Download To-Do Extension Source (Part 3)

published in Chrome Extensions