Skip to content

Instantly share code, notes, and snippets.

@cmwright
Last active August 29, 2015 14:02
Show Gist options
  • Save cmwright/6dec1c85068e40833f1f to your computer and use it in GitHub Desktop.
Save cmwright/6dec1c85068e40833f1f to your computer and use it in GitHub Desktop.
Backbone FilterMenu POC
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.7/backbone.localStorage-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.2/typeahead.bundle.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.marionette/1.8.6/backbone.marionette.min.js"></script>
<script type='text/javascript'>
_.templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
$(function() {
menu = new app.FilterMenu();
});
var app = {}, menu;
app.FilterMenu = Backbone.Model.extend({
initialize: function() {
this.$selected_items = $("#player_menu .selected_items");
this.$typeahead = $("#player_menu .typeahead");
this.menuItems = new app.FilterMenuItems();
this.availableItems = new app.FilterMenuItems(this.menuItems.available());
this.selectedItems = new app.FilterMenuItems(this.menuItems.selected());
this.selectedItemsView = new app.SelectedItemsView({
collection: this.selectedItems
});
this.listenTo(this.menuItems, 'change:isSelected', this.updateItemCollections);
this.typeahead = this.initializeTypeahead();
this.$selected_items.html(this.selectedItemsView.render().el);
},
updateItemCollections: function(item, isSelected, opts) {
if (isSelected) {
this.availableItems.remove(item);
this.selectedItems.add(item);
} else {
this.selectedItems.remove(item);
this.availableItems.add(item);
}
},
initializeTypeahead: function() {
var self = this;
var typeahead_data = self.menuItems.map(function(menu_item) {
return _.extend(menu_item.toJSON(), {menu: self});
});
var menu_bloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('displayValue'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: typeahead_data
});
menu_bloodhound.initialize();
var typeahead = this.$typeahead.typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'filter_bar',
displayKey: 'displayValue',
source: menu_bloodhound.ttAdapter()
});
typeahead.on('typeahead:selected', function(evt, item_data) {
var menu_item = item_data.menu.menuItems.findWhere({
id: item_data.id
});
menu_item.set('isSelected', true);
});
return {
typeahead: typeahead,
bloodhound: menu_bloodhound
};
}
});
app.FilterMenuItem = Backbone.Model.extend({
defaults: {
displayValue: null,
isSelected: false
}
});
app.FilterMenuItems = Backbone.Collection.extend({
model: app.FilterMenuItem,
initialize: function() {
this.fetch();
},
fetch: function() {
for (var i = 0; i < 10000; i++) {
this.add({
displayValue: '' + i,
id: i
});
}
},
available: function() {
return this.where({
isSelected: false
});
},
selected: function() {
return this.where({
isSelected: true
});
}
});
app.SelectedItemView = Marionette.ItemView.extend({
tagName: "li",
className: "selected_item",
template: "#selected_item_tmpl",
events: {
"click .remove_filter": "destroy"
},
destroy: function(){
this.model.set('isSelected', false);
}
});
app.SelectedItemsView = Marionette.CollectionView.extend({
itemView: app.SelectedItemView,
tagName: 'ul',
className: 'selected_items'
});
</script>
</head>
<body>
<script id='selected_item_tmpl' type='text/template'>
<span class='filter_title'>{{ displayValue }}</span>
<a class='remove_filter' href='#'>X</a>
</script>
<div id='player_menu'>
<input class='typeahead' type='text' placeholder='Item'>
<div class='selected_items'></div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment