xosDeveloper view marionette wip
[plstackapi.git] / planetstack / core / xoslib / static / js / angrycats.js
1 MyApp = new Backbone.Marionette.Application();
2
3 MyApp.addRegions({
4     mainRegion: "#content"
5 });
6
7 AngryCat = 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
25 AngryCats = 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
102 AngryCatView = 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
133 AngryCatsView = 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
149 MyApp.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 });