Building Checklist.js library using HTML5 Local Storage and Backbone.js

In this post I am going to describe how I created Checklist.js library, which turns HTML lists on your page into chekclists. It adds checkboxs to list items and stores data in the HTML5 Local Storage, so the user could to see his/her checklist(s) after reloading a page or restarting a browser.

It's continent isn't it? You can check out a live demo and a Backbone.js, Underscore.js and jQuery libraries. As for storing data in the HTML5 Local Storage I used Backbone.localStorage extension.

Let's go deep into a code!

  1. First I defined CheckBoxModel, which contains a boolean value whether a checkbox is checked or not.
      var CheckBoxModel = Backbone.Model.extend({
        defaults: {
          checked: false
        },
      });
    
  2. Then I defined CheckBoxCollection, which stores our models. Also I have introduced gain() method, which tries to get a model with a specific id or creates a new one with such id.
      // Define the collection.
      var CheckBoxCollection = Backbone.Collection.extend({
        model: CheckBoxModel,
    
        // Gets an existing model, otherwise creates new and returns.
        gain: function(id) {
          if (!this.get(id)) {
            this.add({ id: id });
          }
          return this.get(id);
        }
      });
    
  3. Now let's define CheckBoxView that renders CheckBoxModel. This view is bound to a model, so when the model is updated a view gets updated automatically and vice-verse.
      var CheckBoxView = Backbone.View.extend({
        tagName: 'input',
    
        attributes: {
          type: 'checkbox'
        },
    
        events: {
          'change': 'change'
        },
    
        initialize: function() {
          this.listenTo(this.model, 'change', this.render);
        },
    
        render: function() {
          this.$el.attr('checked', this.model.get('checked'));
    
          return this;
        },
    
        change: function () {
          this.model.save({ checked: this.$el.is(':checked') });
        }
      });
    
  4. Next, we should define ListItemView that is associated with a list item, which wraps it's content into label tag and prepends CheckBoxView.
      var ListItemView = Backbone.View.extend({
        initialize: function() {
          var checkBoxView = new CheckBoxView({ model: this.model });
          this.$el
            .prepend(checkBoxView.render().el)
            .wrapInner('');
    
          this.listenTo(this.model, 'change', this.update);
          this.update();
        },
    
        update: function() {
          this.$el.attr('data-checked', this.model.get('checked'));
        },
      });
    
  5. And finally let's add attachChecklist() function, which attaches ListItemView to a list item and gains a model from a collection. It uses list element id and list item index to create a unique identifier for a checkbox.
  6.   var attachChecklist = function(checklist) {
        $('.checklist').each(function(index) {
    
          // Get an HTML list ID.
          var checklistId = $(this).attr('id') || '_checklist_' +  index + '_';
    
          $(this).find('>li').each(function(index) {
    
            // Attach a view to a list item.
            new ListItemView({
              el: $(this),
              model: checklist.gain(checklistId + '-' + index)
            });
          });
        });
      };
    
  7. And now the most interesting part, where we return init() function, which creates HTML5 Local Storage and passes it to the collection. To get data from the storage we should call fetch() method of the collection.
      return {
        init: function(storageId) {
    
          // Set falback storage ID based on the current URL.
          storageId = storageId ||  window.location.origin + window.location.pathname;
    
          // Create local storage with given ID.
          _.extend(CheckBoxCollection.prototype, {
            localStorage: new Backbone.LocalStorage(storageId)
          });
    
          // Create collection instance.
          this.checklist = new CheckBoxCollection();
    
          // Fetch data from the storage.
          this.checklist.fetch({ success: attachChecklist });
        }
      }
    

Here it is! Our extension works as expected. You can check out a live demo and find more interesting recipes about Backbone models, collections, views, REST and HTML5 Local Storage in the Backbone.js Cookbook.

Similar Entries