Javascript MVC: a simple todo list

Download the source

You can download, and check the source from my github account

A lot of beginning javascript developers might find it hard to start with design patterns. And for most projects larger frameworks, for example backbone.js would be overkill. I created a very simple todo example application based on mvc. I tried to keep the app as clean and concise as possible. Therefore the application is “ugly”, no styling no images etc. I did use jQuery for event dispatching, to my opinion this easier to understand and to maintain than pure javascript events.

Application structure

The application has three main classes and i did not follow the mvc pattern really strictly, for example i could have implemented the model more strictly, with getters an setters, and for example use a singleton for for the model. I did however decoupled the model from the view by the controller.

The Model

The model module is essentially one private array which stores the todo items and is exposed by some public methods.

var Model = function () {
        var _todos = new Array();    

	var notifyController = function () {	
            $('body').trigger('updateView');
	}
        // public methods
	return  {
		addTodo: function ( todo ) {
                    _todos.push(todo);
                   notifyController();
		},
                editTodo: function( index, newTodo ){
                    _todos[index] = newTodo;
                },
                deleteTodo: function ( index ) {
                   _todos.splice(index,1);
                   notifyController();
		},
                getData: function(){
                    return _todos;
                }
	};
};

The View

the view module below handles the user events and updates the view (html file). The view is coupled with the html file. The main events are the “add-event”, triggered by the “add” link and the enter key, and the delete event which the “delete” link triggers.

var View = function () {
	var updateView = function ( todos ) {	
            $('#todoList li').remove();
            for( var i = 0, len = todos.length; i < len; i++ ){
              $('#todoList')
               .append( '<li>' + todos[i] 
               + '<a data-index="' + i + '" href="#">remove</a></li>');
            }
	};
        
        //set the handlers for the view
        var initView = function(){
            //add
            $("#addTodoButton").on("click", function(){
                var event = jQuery.Event("addItem");
                event.todo = $('#addTodo')[0].value;
                $('body').trigger(event);
                $('#addTodo')[0].value = '';
            });
            // track enter key
            $('#addTodo').on("keypress", function(e){
              if(e.which == 13){
                var event = jQuery.Event("addItem");
                event.todo = $('#addTodo')[0].value;
                $('body').trigger(event);
                $('#addTodo')[0].value = '';
               }
              });

            //delete
            $('#todoList a').live("click", function(e){
                var $todo = e.currentTarget;
                var event = jQuery.Event("deleteItem");
                event.index = $($todo).attr('data-index');
                $('body').trigger(event);
            });
        };
        initView();
        
	return  {
		updateView: function (todos) {
                    updateView(todos);
		}
	};
};

The Controller

The controller module listens for the events disposed by the view module, the controller is aware of the model and the view.

var Controller = function (view, model) {
        var _view = view;
        var _model = model;

        // event binding
        $('body').bind('addItem', function(e) {
           _model.addTodo( e.todo );
        });
         $('body').bind('deleteItem', function(e) {
           _model.deleteTodo( e.index );
        });
        $('body').bind('updateView', function(e) {
            _view.updateView( _model.getData() );
        });
};

The Application

The last script is the simple initialize script which binds the MVC modules together. The model and the view are instantiated and passed to the controller.

//init
var model = Model();
var view = View();
var controller = Controller(view, model);

The current application is very simple. If the app would be extended I would start by creating a “todo” view item, this would separate the single todo item from the listing ( and perhaps sorting ) of the todo items. Extending applications like this maintain a clear separation of functions, which definitely helps if an applications grows larger.

Download the source

You can download, and check the source from my github account

Book review: JavaScript Web Applications

Book cover of Javacript Web Applications

  • Author: Alex MacCaw
  • publisher: O’Reilly Media
  • pages: 280

Introduction

A book to create javascript applications for the intermediate javascript developer. This book gives you a kickstart, helps you choose the right framework, and architectural choices for your application

Review

The book has a fast pace, no thoroughly introduction of MVC, I think this is justified. MVC has been explained a lot of times the last decade. The author of this book explains a lot of modern frameworks en modern technologies

This book is not for the novice javscript developers even the intermediate developers can have a hard task grasping the contents of this book. You need to understand the core of javascript and jQuery as well as design patterns, at least a couple of them to get the most out of this book.

Personally for me the topic of this book is a bit overkill for the web applications I develop. Hence if the scale of my webapps grows more complex I will definitely turn to this book. It will explain a lot of usefull state of the art Javascript MVC frameworks.

After explaining several ways of working with events in javascript application the author starts digging into MVC. First a chapter on Models and ORM (Object-relational mapping) and how to populate your model with external data. Offline as well as online storage of the model is also described in this chapter. The next chapter is about the controller, the best ways of event delegation and accessing the views. And finally the views itself, with modern js templating techniques. After the MVC foundation Spine.js and Backbone.js are introduced and explained. Two of the most known patterns for small ( spine.js ) to large ( Backbone.js ) web applications.

I also liked to addional information on modern topics like LESS ans CSS 3 and NodeJS. For me this was pure complementary information, and I had rather seen some more introduction in the beginning.

Bottom line

JavaScript Web Application is a must have book to plan and develop larger applications. It tells you everything you need to know to structure a application, but I think it would help to read other book before this book to get the most out of it, for example Javascript Patterns. The books product page