blob: a599a83932c55ce155e2e3aa224c72f02b5d37f5 [file] [log] [blame]
Scott Baker7ee32a02014-07-13 09:52:15 -07001MyApp = new Backbone.Marionette.Application();
2
3MyApp.addRegions({
4 mainRegion: "#content"
5});
6
7AngryCat = Backbone.Model.extend({
8 defaults: {
9 votes: 0
10 },
11
12 addVote: function(){
13 this.set('votes', this.get('votes') + 1);
14 },
15
16 rankUp: function() {
17 this.set({rank: this.get('rank') - 1});
18 },
19
20 rankDown: function() {
21 this.set({rank: this.get('rank') + 1});
22 }
23});
24
25AngryCats = Backbone.Collection.extend({
26 model: AngryCat,
27
28 initialize: function(cats){
29 var rank = 1;
30 _.each(cats, function(cat) {
31 cat.set('rank', rank);
32 ++rank;
33 });
34
35 this.on('add', function(cat){
36 if( ! cat.get('rank') ){
37 var error = Error("Cat must have a rank defined before being added to the collection");
38 error.name = "NoRankError";
39 throw error;
40 }
41 });
42
43 var self = this;
44
45 MyApp.on("rank:up", function(cat){
46 if (cat.get('rank') === 1) {
47 // can't increase rank of top-ranked cat
48 return true;
49 }
50 self.rankUp(cat);
51 self.sort();
52 self.trigger("reset");
53 });
54
55 MyApp.on("rank:down", function(cat){
56 if (cat.get('rank') === self.size()) {
57 // can't decrease rank of lowest ranked cat
58 return true;
59 }
60 self.rankDown(cat);
61 self.sort();
62 self.trigger("reset");
63 });
64
65 MyApp.on("cat:disqualify", function(cat){
66 var disqualifiedRank = cat.get('rank');
67 var catsToUprank = self.filter(
68 function(cat){ return cat.get('rank') > disqualifiedRank; }
69 );
70 catsToUprank.forEach(function(cat){
71 cat.rankUp();
72 });
73 self.trigger('reset');
74 });
75 },
76
77 comparator: function(cat) {
78 return cat.get('rank');
79 },
80
81 rankUp: function(cat) {
82 // find the cat we're going to swap ranks with
83 var rankToSwap = cat.get('rank') - 1;
84 var otherCat = this.at(rankToSwap - 1);
85
86 // swap ranks
87 cat.rankUp();
88 otherCat.rankDown();
89 },
90
91 rankDown: function(cat) {
92 // find the cat we're going to swap ranks with
93 var rankToSwap = cat.get('rank') + 1;
94 var otherCat = this.at(rankToSwap - 1);
95
96 // swap ranks
97 cat.rankDown();
98 otherCat.rankUp();
99 }
100});
101
102AngryCatView = Backbone.Marionette.ItemView.extend({
103 template: "#angry_cat-template",
104 tagName: 'tr',
105 className: 'angry_cat',
106
107 events: {
108 'click .rank_up img': 'rankUp',
109 'click .rank_down img': 'rankDown',
110 'click a.disqualify': 'disqualify'
111 },
112
113 initialize: function(){
114 this.listenTo(this.model, "change:votes", this.render);
115 },
116
117 rankUp: function(){
118 this.model.addVote();
119 MyApp.trigger("rank:up", this.model);
120 },
121
122 rankDown: function(){
123 this.model.addVote();
124 MyApp.trigger("rank:down", this.model);
125 },
126
127 disqualify: function(){
128 MyApp.trigger("cat:disqualify", this.model);
129 this.model.destroy();
130 }
131});
132
133AngryCatsView = Backbone.Marionette.CompositeView.extend({
134 tagName: "table",
135 id: "angry_cats",
136 className: "table-striped table-bordered",
137 template: "#angry_cats-template",
138 itemView: AngryCatView,
139
140 initialize: function(){
141 this.listenTo(this.collection, "sort", this.renderCollection);
142 },
143
144 appendHtml: function(collectionView, itemView){
145 collectionView.$("tbody").append(itemView.el);
146 }
147});
148
149MyApp.addInitializer(function(options){
150 var angryCatsView = new AngryCatsView({
151 collection: options.cats
152 });
153 MyApp.mainRegion.show(angryCatsView);
154});
155
156$(document).ready(function(){
157 var cats = new AngryCats([
158 new AngryCat({ name: 'Wet Cat', image_path: 'assets/images/cat2.jpg' }),
159 new AngryCat({ name: 'Bitey Cat', image_path: 'assets/images/cat1.jpg' }),
160 new AngryCat({ name: 'Surprised Cat', image_path: 'assets/images/cat3.jpg' })
161 ]);
162
163 MyApp.start({cats: cats});
164
165 cats.add(new AngryCat({
166 name: 'Cranky Cat',
167 image_path: 'assets/images/cat4.jpg',
168 rank: cats.size() + 1
169 }));
170});