Selectable entities as mixins for Backbone.Views in a Backbone.BabySitter ChildViewContainer!
At the moment, I'd recommend using this library with my custom fork of Backbone.BabySitter, rather than the original Backbone.BabySitter, simply because my custom fork provides the ability to define an initialize
method on the ChildViewContainer, either by .extend
-ing it (another added capability of my fork) or by passing an initialize
function as a property of the ChildViewContainer
's options
hash. This makes it easy to have a ChildViewContainer
initialize itself as SingleSelectable
or MultiSelectable
, and provides an easy way to make any view added to the container Selectable
as well. Still, it's entirely possible to do that with the original BabySitter, I just find it easier with my own fork.
You can download the raw source code from the "src" folder above, or grab one of the builds from the "lib" folder. To get the latest stable release, use these links which point to the 'master' branch's builds:
Development: backbone.pickysitter.js
Production: backbone.picky.min.js
Development: backbone.pickysitter.js
Production: backbone.picky.min.js
This readme file contains basic usage examples and details on the full API, including methods, attributes and events.
If you implement a Selectable
view, the methods on the views and theMultiSelect
container will keep each other in sync. That is, if youcall view.select()
on a view, the container will be notified of theview being selected and it will correctly update the selectedLength
andfire the correct events.
Therefore, the following are functionally the same:
view = new MyView();
col = new MyContainer([view]);
view.select();
view = new MyView();
col = new MyContainer([view]);
col.select(view);
Your view for a Picky container must implement the following API to beusable by the selection methods and functionality:
select: function(){...}
deselect: function(){...}
The easiest way to do this is to have your view extend Selectable
. Youcan, however, implement your own version of these methods.
- Picky.Selectable: Creates select / deselect capabilities for a view
- Picky.MultiSelect: Allows a container to know about the selection of multiple views, including select all / deselect all
- Picky.SingleSelect: Allow a container to have an exclusively selected view
Creates selectable capabilities for a view, including tracking whether ornot the view is selected, and raising events when selection changes.
var selectable = new Backbone.PickySitter.Selectable(myView);
Extend your view with the Selectable
instance to make your viewselectable directly.
SelectableView = Backbone.View.extend({
initialize: function(){
var selectable = new Backbone.PickySitter.Selectable(this);
_.extend(this, selectable);
}
});
The following methods are included in the Selectable
object
Select a view, setting the view's selected
attribute to true and triggering a "select" event.
var myView = new SelectableView();
myView.on("select", function(){
console.log("I'm selected!");
});
myView.select(); //=> logs "I'm selected!"
myView.selected; //=> true
Deselect a view, setting the view's selected
attribute to false and triggering a "deselect" event.
var myView = new SelectableView();
myView.on("deselect", function(){
console.log("I'm no longer selected!");
});
// must select it before it can be deselected
myView.select();
myView.deselect(); //=> logs "I'm no longer selected!";
myView.selected; //=> false
Toggles the selection state between selected and deselected by calling
the select
or deselect
method appropriately.
var myView = new SelectableView();
myView.on("select", function(){
console.log("I'm selected!");
});
myView.on("deselect", function(){
console.log("I'm no longer selected!");
});
// toggle selection
myView.toggleSelected(); //=> "I'm selected!"
myView.toggleSelected(); //=> "I'm no longer selected!"
The following attributes are manipulated by the Selectable object
Returns a boolean value indicating whether or not the view is currently selected.
The following events are triggered from Selectable views
Triggers when a view is selected.
Triggers when a view is deselected.
Creates single-select capabilities for a Backbone.ChildViewContainer
, allowing a single view to be exclusively selected within the container. Selecting another view will cause the first one to be deselected.
var singleSelect = new Backbone.PickySitter.SingleSelect(myContainer) ;
Extend your container with the SingleSelect
instance to make your container support exclusive selections directly.
SelectableView = Backbone.View.extend({
initialize: function(){
var selectable = new Backbone.PickySitter.Selectable(this);
_.extend(this, selectable);
}
});
SingleContainer = Backbone.ChildViewContainer.extend({
view: SelectableView,
initialize: function(){
var singleSelect = new Backbone.PickySitter.SingleSelect(this);
_.extend(this, singleSelect);
}
});
The following methods are provided by the SingleSelect
object.
Select a view. This method will store the selected view in the container's selected
attribute, and call the view's select
method to ensure the view knows it has been selected.
myView = new SelectableView();
myCont = new MultiContainer();
myCont.select(myView);
Or
myView = new SelectableView();
myCont = new MultiContainer([myView]);
myView.select();
If the view is already selected, this is a no-op. If a previous view is already selected, the previous view will be deselected.
Deselect the currently selected view. This method will remove the view from the container's selected
attribute, and call the view's deselect
method to ensure the view knows it has been deselected.
myView = new SelectableView();
myCont = new MultiContainer();
myCont.deselect(myView);
Or
myView = new SelectableView();
myCont = new MultiContainer();
myView.deselect();
If the view is not currently selected, this is a no-op. If you try todeselect a view that is not the currently selected view, the actualselected view will not be deselected.
The following attribute is set by the multi-select automatically
Returns the one selected view for this container
myCont = new MultiContainer();
myCont.select(view);
myCont.selected; //=> view
The following events are triggered by the MultiSelect based on changes in selection:
Triggered when a view has been selected. Provides the selected view as the first parameter.
Triggered when a view has been deselected. Provides the deselected view as the first parameter.
This fires whether deselect
has been called explicitly, or the selection is being replace through another call to select
.
Creates multi-select capabilities for a Backbone.ChildViewContainer
, including select all, select none and select some features.
var multiSelect = new Backbone.PickySitter.MultiSelect(myContainer) ;
Extend your container with the MultiSleect
instance to make your container support multiple selections directly.
SelectableView = Backbone.View.extend({
initialize: function(){
var selectable = new Backbone.PickySitter.Selectable(this);
_.extend(this, selectable);
}
});
MultiContainer = Backbone.ChildViewContainer.extend({
view: SelectableView,
initialize: function(){
var multiSelect = new Backbone.PickySitter.MultiSelect(this);
_.extend(this, multiSelect);
}
});
The following methods are provided by the MultiSelect
object
Select a view. This method will store the selected view in the container's selected
list, and call the view's select
method to ensure the view knows it has been selected.
myCont = new MultiContainer();
myCont.select(myView);
If the view is already selected, this is a no-op.
Deselect a view. This method will remove the view from the container's selected
list, and call the view's deselect
method to ensure the view knows it has been deselected.
myCont = new MultiContainer();
myCont.deselect(myView);
If the view is not currently selected, this is a no-op.
Select all views in the container.
myCont = new MultiContainer();
myCont.selectAll();
Views that are already selected will not be re-selected. Views that are not currently selected will be selected. The end result will be all views in the container are selected.
Deselect all views in the container.
myCont = new MultiContainer();
myCont.deselectAll();
Views that are selected will be deselected. Views that are not selected will not be deselected again. The end result will be no views in the container are selected.
Toggle selection of all views in the container:
myCont = new MultiContainer();
myCont.toggleSelectAll(); // select all views in the container
myCont.toggleSelectAll(); // de-select all views in the container
The following rules are used when toggling:
- If no views are selected, select them all
- If 1 or more views, but less than all views are selected, select them all
- If all views are selected, deselect them all
The following attribute is set by the multi-select automatically
Returns a hash of selected views, keyed from the view's cid
.
myCont = new MultiContainer();
myCont.select(view);
myCont.selected;
//=> produces
// {
// "c1": (view object here)
// }
Returns the number of items in the container that are selected.
myCont = new MultiContainer();
myCont.select(view);
myCont.selectedLength; //=> 1
The following events are triggered by the MultiSelect based on changes in selection:
Triggered when all views have been selected
Triggered when all views have been deselected
Triggered when at least 1 view is selected, but less than all views have been selected
If you wish to build Backbone.PickySitter on your system, you will need Ruby to run the Jasmine specs, and NodeJS to run the grunt build.
- Don't even try, they haven't been updated since this worked on models and collections
-
Be sure you have NodeJS and NPM installed on your system
-
Run
npm install -g grunt
to install the grunt build system -
From the project folder, run
grunt
to produce a build
- Refactored [Backbone.Picky] to work on Views contained in a Backbone.ChildViewContainer
Copyright (c) 2012 Jeremy McLeod, Isochronous.org
Huge thanks to Derick Bailey of Muted Solutions LLC, from whose code this library is almost entirely based.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.