Skip to content

Viewmodels for selectable collections and models

derickbailey edited this page May 29, 2012 · 1 revision

This ViewModels module make it easy to build a view model set up for your models and collections. This allows you to have general-purpose models that can be re-used in scenarios where one or more of the items need to be selected.

// Create a `ViewModels` module
ViewModels = (function(Backbone, _){
    var ViewModels = {};

    // Selectable ViewModel Builders
    // -----------------------------

    ViewModels.buildSelectableModel = function (model) {
        var selectableModel = Object.create(model);
        var selectable = new Backbone.Picky.Selectable(model);
        return _.extend(selectableModel, selectable);
    }

    ViewModels.buildMultiSelectList = function (list) {
        return buildSelectableList(list, "MultiSelect");
    };

    ViewModels.buildSingleSelectList = function (list) {
        return buildSelectableList(list, "SingleSelect");
    };

    // Helpers
    // -------

    var buildListItems = function (selectableList, originalList) {
        originalList.each(function (model) {
            var selectableModel = ViewModels.buildSelectableModel(model);
            selectableList.add(selectableModel);
            selectableModel.collection = selectableList;
        });
    };

    var buildSelectableList = function (originalList, ListType) {
        var selectableList = new Backbone.Collection();
        var selectableMixin = new Backbone.Picky[ListType](selectableList);
        _.extend(selectableList, selectableMixin);

        originalList.on("reset", function () {
            buildListItems(selectableList, originalList);
        }, this);

        buildListItems(selectableList, originalList);

        return selectableList;
    }

    return ViewModels;
})(Backbone, _);

This code is best used in scenarios where you need selectable models and collections without any significant business logic on the models or collections.

Example: Select A Credit Card

If you're users have credit cards on file and they need to select one, you could set up selectable view models like this:

var myCreditCards = new CreditCardCollection();

var selectableCards = ViewModels.buildSingleSelectList(myCreditCards);

var view = new CreditCardChooserView({
  collection: selectableCards
});

// ... render, display, etc.

Now you can call model.select() on a specific model instance, based on user interaction with the view, and have a single credit card selected.

Example: Manage Movies In A Queue

If you have a website that allows you to manage movies in a queue, you might want to let a user select multiple movies in their queue so that they can remove them all or move them all to the top, etc.

var myMovies = new MovieCollection();

var selectableMovies = ViewModels.buildMultiSelectList(myMovies);

var view = new MovieQueueView({
  collection: selectableMovies
});

// ... render, display, etc.

Now you can call model.select() on multiple models, based on user interaction with the view. Then you could listen to the selected:none, selected:some, and selected:all events from the MultiSelect list and enable / disable certain buttons based on how many are selected.