Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / ui / static / snf / js / views_ext.js @ 89d02c7e

History | View | Annotate | Download (19.6 kB)

1 4b997f54 Kostas Papadimitriou
;(function(root){
2 4b997f54 Kostas Papadimitriou
    
3 4b997f54 Kostas Papadimitriou
    // root
4 4b997f54 Kostas Papadimitriou
    var root = root;
5 4b997f54 Kostas Papadimitriou
    
6 4b997f54 Kostas Papadimitriou
    // setup namepsaces
7 4b997f54 Kostas Papadimitriou
    var snf = root.synnefo = root.synnefo || {};
8 4b997f54 Kostas Papadimitriou
    var models = snf.models = snf.models || {}
9 4b997f54 Kostas Papadimitriou
    var storage = snf.storage = snf.storage || {};
10 4b997f54 Kostas Papadimitriou
    var ui = snf.ui = snf.ui || {};
11 4b997f54 Kostas Papadimitriou
    var util = snf.util || {};
12 4b997f54 Kostas Papadimitriou
    var views = snf.views = snf.views || {}
13 4b997f54 Kostas Papadimitriou
14 4b997f54 Kostas Papadimitriou
    // shortcuts
15 4b997f54 Kostas Papadimitriou
    var bb = root.Backbone;
16 4b997f54 Kostas Papadimitriou
    
17 4b997f54 Kostas Papadimitriou
    // logging
18 4b997f54 Kostas Papadimitriou
    var logger = new snf.logging.logger("SNF-VIEWS");
19 4b997f54 Kostas Papadimitriou
    var debug = _.bind(logger.debug, logger);
20 4b997f54 Kostas Papadimitriou
21 4b997f54 Kostas Papadimitriou
    // Extended views module
22 4b997f54 Kostas Papadimitriou
    // View objects to provide more sophisticated base objects for views 
23 4b997f54 Kostas Papadimitriou
    // that are bind to existing storage model/collection objects.
24 4b997f54 Kostas Papadimitriou
    views.ext = {};
25 4b997f54 Kostas Papadimitriou
    
26 4b997f54 Kostas Papadimitriou
    views.ext.View = views.View.extend({
27 4b997f54 Kostas Papadimitriou
      rivets_view: false,
28 4b997f54 Kostas Papadimitriou
      rivets: undefined,
29 365af933 Kostas Papadimitriou
      container: undefined,
30 365af933 Kostas Papadimitriou
      classes:'',
31 4b997f54 Kostas Papadimitriou
32 4b997f54 Kostas Papadimitriou
      storage_handlers: {},
33 4b997f54 Kostas Papadimitriou
34 4b997f54 Kostas Papadimitriou
      init: function() {},
35 4b997f54 Kostas Papadimitriou
      post_init: function() {},
36 4b997f54 Kostas Papadimitriou
37 365af933 Kostas Papadimitriou
      initialize: function(options) {
38 f9f43e09 Kostas Papadimitriou
        views.ext.View.__super__.initialize.apply(this, arguments);
39 365af933 Kostas Papadimitriou
        this.container = options && options.container;
40 4b997f54 Kostas Papadimitriou
        this._subviews = [];
41 4b997f54 Kostas Papadimitriou
        if (this.tpl) {
42 4b997f54 Kostas Papadimitriou
          this.el = $(this.tpl).clone().removeClass("hidden").removeAttr('id');
43 4b997f54 Kostas Papadimitriou
        }
44 4b997f54 Kostas Papadimitriou
        this.init.apply(this, arguments);
45 4b997f54 Kostas Papadimitriou
        this.post_init.apply(this, arguments);
46 365af933 Kostas Papadimitriou
        this.append_to_container();
47 365af933 Kostas Papadimitriou
        $(this.el).addClass(this.classes);
48 4b997f54 Kostas Papadimitriou
        _.bindAll(this);
49 4b997f54 Kostas Papadimitriou
      },
50 365af933 Kostas Papadimitriou
      
51 365af933 Kostas Papadimitriou
      append_to_container: function() {
52 365af933 Kostas Papadimitriou
        if (!this.container) { return }
53 365af933 Kostas Papadimitriou
        var cont = $(this.container);
54 365af933 Kostas Papadimitriou
        cont.append(this.el);
55 365af933 Kostas Papadimitriou
      },
56 4b997f54 Kostas Papadimitriou
57 4b997f54 Kostas Papadimitriou
      create_view: function(view_cls, options) {
58 4b997f54 Kostas Papadimitriou
        var options = _.extend({}, options);
59 4b997f54 Kostas Papadimitriou
        options.parent_view = this;
60 4b997f54 Kostas Papadimitriou
        var view = new view_cls(options);
61 9145aad9 Kostas Papadimitriou
        if (view.css_classes) {
62 9145aad9 Kostas Papadimitriou
          view.el.addClass(view.css_classes)
63 9145aad9 Kostas Papadimitriou
        }
64 4b997f54 Kostas Papadimitriou
        return view;
65 4b997f54 Kostas Papadimitriou
      },
66 4b997f54 Kostas Papadimitriou
67 4b997f54 Kostas Papadimitriou
      add_subview: function(view) {
68 4b997f54 Kostas Papadimitriou
        view.parent_view = this;
69 4b997f54 Kostas Papadimitriou
        this._subviews.push(view);
70 4b997f54 Kostas Papadimitriou
      },
71 4b997f54 Kostas Papadimitriou
72 4b997f54 Kostas Papadimitriou
      remove_view: function(view) {
73 4b997f54 Kostas Papadimitriou
        this._subviews = _.without(this._subviews, view);
74 4b997f54 Kostas Papadimitriou
      },
75 4b997f54 Kostas Papadimitriou
      
76 4b997f54 Kostas Papadimitriou
      hide_subviews: function() {
77 4b997f54 Kostas Papadimitriou
        _.each(this._subviews, function(view) { 
78 4b997f54 Kostas Papadimitriou
          view.hide(true); 
79 4b997f54 Kostas Papadimitriou
        });
80 4b997f54 Kostas Papadimitriou
      },
81 4b997f54 Kostas Papadimitriou
82 4b997f54 Kostas Papadimitriou
      show_subviews: function() {
83 4b997f54 Kostas Papadimitriou
        _.each(this._subviews, function(view) { 
84 4b997f54 Kostas Papadimitriou
          view.show(true); 
85 4b997f54 Kostas Papadimitriou
        });
86 4b997f54 Kostas Papadimitriou
      },
87 4b997f54 Kostas Papadimitriou
      
88 4b997f54 Kostas Papadimitriou
      pre_hide: function() {
89 4b997f54 Kostas Papadimitriou
        this.rivets_unbind();
90 4b997f54 Kostas Papadimitriou
        this.remove_handlers();
91 4b997f54 Kostas Papadimitriou
      },
92 4b997f54 Kostas Papadimitriou
      
93 4b997f54 Kostas Papadimitriou
      get_extra_rivet_models: function() {},
94 4b997f54 Kostas Papadimitriou
95 4b997f54 Kostas Papadimitriou
      get_rivet_object: function() {
96 4b997f54 Kostas Papadimitriou
        return this.rivet_object;
97 4b997f54 Kostas Papadimitriou
      },
98 4b997f54 Kostas Papadimitriou
99 4b997f54 Kostas Papadimitriou
      post_hide: function() {
100 4b997f54 Kostas Papadimitriou
        this.hide_subviews();
101 4b997f54 Kostas Papadimitriou
        this.trigger("hide");
102 4b997f54 Kostas Papadimitriou
      },
103 4b997f54 Kostas Papadimitriou
      
104 4b997f54 Kostas Papadimitriou
      rivets_init: function() {
105 4b997f54 Kostas Papadimitriou
        if (!this.rivets_view) { return }
106 4b997f54 Kostas Papadimitriou
        var rivet_object = this.get_rivet_object();
107 4b997f54 Kostas Papadimitriou
        rivet_object['view'] = this;
108 4b997f54 Kostas Papadimitriou
        if (this.el != $("body").get(0)) {
109 4b997f54 Kostas Papadimitriou
          this.rivets = rivets.bind(this.el, rivet_object);
110 4b997f54 Kostas Papadimitriou
        } else {
111 4b997f54 Kostas Papadimitriou
        }
112 4b997f54 Kostas Papadimitriou
      },
113 4b997f54 Kostas Papadimitriou
      
114 4b997f54 Kostas Papadimitriou
      rivets_update: function() {
115 4b997f54 Kostas Papadimitriou
        if (!this.rivets_view) { return }
116 4b997f54 Kostas Papadimitriou
        this.rivets.update();
117 4b997f54 Kostas Papadimitriou
      },
118 4b997f54 Kostas Papadimitriou
119 4b997f54 Kostas Papadimitriou
      rivets_bind: function() {
120 4b997f54 Kostas Papadimitriou
        if (!this.rivets_view) { return }
121 4b997f54 Kostas Papadimitriou
        if (!this.rivets) { this.rivets_init(); return }
122 4b997f54 Kostas Papadimitriou
        var rivet_object = this.get_rivet_object();
123 4b997f54 Kostas Papadimitriou
        rivet_object['view'] = this;
124 4b997f54 Kostas Papadimitriou
        this.rivets.models = rivet_object;
125 4b997f54 Kostas Papadimitriou
        //this.rivets.build();
126 4b997f54 Kostas Papadimitriou
        this.rivets.bind();
127 4b997f54 Kostas Papadimitriou
      },
128 4b997f54 Kostas Papadimitriou
129 4b997f54 Kostas Papadimitriou
      rivets_unbind: function() {
130 4b997f54 Kostas Papadimitriou
        if (!this.rivets_view) { return }
131 f9f43e09 Kostas Papadimitriou
        if (!this.rivets) { return }
132 4b997f54 Kostas Papadimitriou
        this.rivets.unbind();
133 4b997f54 Kostas Papadimitriou
      },
134 4b997f54 Kostas Papadimitriou
135 4b997f54 Kostas Papadimitriou
      pre_show: function() {
136 4b997f54 Kostas Papadimitriou
        this.set_handlers();
137 4b997f54 Kostas Papadimitriou
        this.rivets_bind();
138 4b997f54 Kostas Papadimitriou
        this.show_subviews();
139 4b997f54 Kostas Papadimitriou
      },
140 4b997f54 Kostas Papadimitriou
      
141 4b997f54 Kostas Papadimitriou
      resolve_storage_object: function(id) {
142 4b997f54 Kostas Papadimitriou
        var result;
143 4b997f54 Kostas Papadimitriou
        if (this['resolve_' + id + '_storage_object']) {
144 4b997f54 Kostas Papadimitriou
          return this['resolve_' + id + '_storage_object']();
145 4b997f54 Kostas Papadimitriou
        }
146 4b997f54 Kostas Papadimitriou
        result = synnefo.storage[id];
147 4b997f54 Kostas Papadimitriou
        return result ? result : this.collection
148 4b997f54 Kostas Papadimitriou
      },
149 4b997f54 Kostas Papadimitriou
      
150 4b997f54 Kostas Papadimitriou
      each_storage_handler: function(cb, context) {
151 4b997f54 Kostas Papadimitriou
        if (!context) { context = this }
152 4b997f54 Kostas Papadimitriou
        _.each(this.storage_handlers, function(handlers, object_name) {
153 4b997f54 Kostas Papadimitriou
          _.each(handlers, function(events, handler_name) {
154 4b997f54 Kostas Papadimitriou
            _.each(events, function(event) {
155 4b997f54 Kostas Papadimitriou
              object = this.resolve_storage_object(object_name);
156 4b997f54 Kostas Papadimitriou
              handler = this['handle_' + handler_name];
157 4b997f54 Kostas Papadimitriou
              if (!handler) {
158 4b997f54 Kostas Papadimitriou
                throw "Handler " + handler_name + " does not exist";
159 4b997f54 Kostas Papadimitriou
              }
160 4b997f54 Kostas Papadimitriou
              if (!object) {
161 4b997f54 Kostas Papadimitriou
                throw "Storage object " + object_name + " does not exist";
162 4b997f54 Kostas Papadimitriou
              }
163 4b997f54 Kostas Papadimitriou
              cb.call(context, object, event, handler);
164 4b997f54 Kostas Papadimitriou
            }, this);
165 4b997f54 Kostas Papadimitriou
          }, this);
166 4b997f54 Kostas Papadimitriou
        }, this);
167 4b997f54 Kostas Papadimitriou
      },
168 4b997f54 Kostas Papadimitriou
      
169 4b997f54 Kostas Papadimitriou
      get_handler: function(id) {
170 4b997f54 Kostas Papadimitriou
      },
171 4b997f54 Kostas Papadimitriou
172 4b997f54 Kostas Papadimitriou
      set_handlers: function() {
173 4b997f54 Kostas Papadimitriou
        this.each_storage_handler(this.set_handler, this);
174 4b997f54 Kostas Papadimitriou
      },
175 4b997f54 Kostas Papadimitriou
176 4b997f54 Kostas Papadimitriou
      remove_handlers: function() {
177 4b997f54 Kostas Papadimitriou
        this.each_storage_handler(this.remove_handler, this);
178 4b997f54 Kostas Papadimitriou
      },
179 4b997f54 Kostas Papadimitriou
      
180 4b997f54 Kostas Papadimitriou
      set_handler: function(object, event, handler) {
181 4b997f54 Kostas Papadimitriou
        object.bind(event, handler);
182 4b997f54 Kostas Papadimitriou
      },
183 4b997f54 Kostas Papadimitriou
184 4b997f54 Kostas Papadimitriou
      remove_handler: function(object, event, handler) {
185 4b997f54 Kostas Papadimitriou
        object.unbind(event, handler);
186 4b997f54 Kostas Papadimitriou
      }
187 4b997f54 Kostas Papadimitriou
    });
188 4b997f54 Kostas Papadimitriou
189 4b997f54 Kostas Papadimitriou
    views.ext.PaneView = views.ext.View.extend({
190 4b997f54 Kostas Papadimitriou
      collection_view_cls: null,
191 4b997f54 Kostas Papadimitriou
      collection_view_selector: '.collection',
192 4b997f54 Kostas Papadimitriou
      init: function() {
193 4b997f54 Kostas Papadimitriou
        var options = {};
194 4b997f54 Kostas Papadimitriou
        options['el'] = $(this.$(this.collection_view_selector).get(0));
195 4b997f54 Kostas Papadimitriou
        this.collection_view = this.create_view(this.collection_view_cls, options);
196 4b997f54 Kostas Papadimitriou
        this.add_subview(this.collection_view);
197 4b997f54 Kostas Papadimitriou
      },
198 4b997f54 Kostas Papadimitriou
    });
199 4b997f54 Kostas Papadimitriou
200 4b997f54 Kostas Papadimitriou
    views.ext.CollectionView = views.ext.View.extend({
201 4b997f54 Kostas Papadimitriou
      collection: undefined,
202 4b997f54 Kostas Papadimitriou
      model_view_cls: undefined,
203 4b997f54 Kostas Papadimitriou
      animation_speed: 200,
204 8e13afa9 Kostas Papadimitriou
      quota_key: undefined,
205 8e13afa9 Kostas Papadimitriou
      quota_limit_message: undefined,
206 4b997f54 Kostas Papadimitriou
207 4b997f54 Kostas Papadimitriou
      init: function() {
208 4b997f54 Kostas Papadimitriou
        var handlers = {};
209 4b997f54 Kostas Papadimitriou
        handlers[this.collection_name] = {
210 4b997f54 Kostas Papadimitriou
          'collection_change': ['update', 'sort'],
211 4b997f54 Kostas Papadimitriou
          'collection_reset': ['reset'],
212 4b997f54 Kostas Papadimitriou
          'model_change': ['change'],
213 4b997f54 Kostas Papadimitriou
          'model_add': ['add'],
214 4b997f54 Kostas Papadimitriou
          'model_remove': ['remove']
215 4b997f54 Kostas Papadimitriou
        }
216 4b997f54 Kostas Papadimitriou
        this.storage_handlers = _.extend(handlers, this.storage_handlers)
217 4b997f54 Kostas Papadimitriou
        this._model_views = {};
218 4b997f54 Kostas Papadimitriou
        this.list_el = $(this.$(".items-list").get(0));
219 4b997f54 Kostas Papadimitriou
        this.empty_el = $(this.$(".empty-list").get(0));
220 4b997f54 Kostas Papadimitriou
        if (this.create_view_cls) {
221 4b997f54 Kostas Papadimitriou
          this._create_view = new this.create_view_cls();
222 8e13afa9 Kostas Papadimitriou
          this._create_view.parent_view = this;
223 4b997f54 Kostas Papadimitriou
        }
224 f784d324 Kostas Papadimitriou
225 f784d324 Kostas Papadimitriou
        this.create_button = this.$(".create-button a");
226 f784d324 Kostas Papadimitriou
        this.create_button.click(_.bind(function(e) {
227 4b997f54 Kostas Papadimitriou
          e.preventDefault();
228 8a563c7c Kostas Papadimitriou
          if (this.$(".create-button a").hasClass("disabled")) {
229 8a563c7c Kostas Papadimitriou
            return;
230 8a563c7c Kostas Papadimitriou
          }
231 4b997f54 Kostas Papadimitriou
          this.handle_create_click();
232 4b997f54 Kostas Papadimitriou
        }, this));
233 8e13afa9 Kostas Papadimitriou
        
234 8e13afa9 Kostas Papadimitriou
        if (this.quota_key && !this.quota) {
235 8e13afa9 Kostas Papadimitriou
          this.quota = synnefo.storage.quotas.get(this.quota_key);
236 8e13afa9 Kostas Papadimitriou
        }
237 8e13afa9 Kostas Papadimitriou
238 8e13afa9 Kostas Papadimitriou
        if (this.quota) {
239 8e13afa9 Kostas Papadimitriou
          this.quota.bind("change", _.bind(this.update_quota, this));
240 8e13afa9 Kostas Papadimitriou
          this.update_quota();
241 8e13afa9 Kostas Papadimitriou
        }
242 8e13afa9 Kostas Papadimitriou
      },
243 8e13afa9 Kostas Papadimitriou
      
244 8e13afa9 Kostas Papadimitriou
      update_quota: function() {
245 8e13afa9 Kostas Papadimitriou
        var available = this.quota.get_available();
246 69dac1ba Kostas Papadimitriou
        if (available > 0) {
247 8e13afa9 Kostas Papadimitriou
          this.create_button.removeClass("disabled");
248 d3e3cba2 Kostas Papadimitriou
          this.create_button.attr("title", "");
249 8e13afa9 Kostas Papadimitriou
        } else {
250 8e13afa9 Kostas Papadimitriou
          this.create_button.addClass("disabled");
251 d3e3cba2 Kostas Papadimitriou
          this.create_button.attr("title", this.quota_limit_message || "Quota limit reached")
252 8e13afa9 Kostas Papadimitriou
        }
253 4b997f54 Kostas Papadimitriou
      },
254 4b997f54 Kostas Papadimitriou
      
255 8e13afa9 Kostas Papadimitriou
      post_create: function() {
256 8e13afa9 Kostas Papadimitriou
        this.quota && this.quota.increase();
257 8e13afa9 Kostas Papadimitriou
      },
258 8e13afa9 Kostas Papadimitriou
259 8e13afa9 Kostas Papadimitriou
      post_destroy: function() {
260 8e13afa9 Kostas Papadimitriou
        this.quota && this.quota.decrease();
261 8e13afa9 Kostas Papadimitriou
      },
262 8e13afa9 Kostas Papadimitriou
263 4b997f54 Kostas Papadimitriou
      handle_create_click: function() {
264 8e13afa9 Kostas Papadimitriou
        if (this.create_button.hasClass("disabled")) { return }
265 8e13afa9 Kostas Papadimitriou
266 4b997f54 Kostas Papadimitriou
        if (this._create_view) {
267 4b997f54 Kostas Papadimitriou
          this._create_view.show();
268 4b997f54 Kostas Papadimitriou
        }
269 4b997f54 Kostas Papadimitriou
      },
270 4b997f54 Kostas Papadimitriou
271 4b997f54 Kostas Papadimitriou
      pre_show: function() {
272 4b997f54 Kostas Papadimitriou
        views.ext.CollectionView.__super__.pre_show.apply(this, arguments);
273 4b997f54 Kostas Papadimitriou
        this.update_models();
274 4b997f54 Kostas Papadimitriou
      },
275 4b997f54 Kostas Papadimitriou
      
276 4b997f54 Kostas Papadimitriou
      handle_collection_reset: function() {
277 4b997f54 Kostas Papadimitriou
        this.update_models();
278 4b997f54 Kostas Papadimitriou
      },
279 4b997f54 Kostas Papadimitriou
280 4b997f54 Kostas Papadimitriou
      handle_model_change: function(model) {
281 4b997f54 Kostas Papadimitriou
        var el, index, model, parent, view, anim;
282 4b997f54 Kostas Papadimitriou
        view = this._model_views[model.id];
283 4b997f54 Kostas Papadimitriou
        if (!view) { return }
284 4b997f54 Kostas Papadimitriou
        el = view.el;
285 4b997f54 Kostas Papadimitriou
        parent = this.parent_for_model(model);
286 69dac1ba Kostas Papadimitriou
        index = this.collection.indexOf(model);
287 4b997f54 Kostas Papadimitriou
        if (!parent.find(el).length) {
288 4b997f54 Kostas Papadimitriou
          anim = true;
289 4b997f54 Kostas Papadimitriou
          this.place_in_parent(parent, el, model, index, anim);
290 4b997f54 Kostas Papadimitriou
        }
291 69dac1ba Kostas Papadimitriou
        if (index != view.el.data('index')) {
292 69dac1ba Kostas Papadimitriou
          this.place_in_parent(parent, el, model, index, false);
293 69dac1ba Kostas Papadimitriou
        }
294 4b997f54 Kostas Papadimitriou
      },
295 4b997f54 Kostas Papadimitriou
296 4b997f54 Kostas Papadimitriou
      handle_collection_change: function() {
297 4b997f54 Kostas Papadimitriou
        this.update_models();
298 4b997f54 Kostas Papadimitriou
      },
299 4b997f54 Kostas Papadimitriou
300 4b997f54 Kostas Papadimitriou
      handle_model_add: function(model, collection, options) {
301 4b997f54 Kostas Papadimitriou
        this.add_model(model);
302 375a9cb5 Kostas Papadimitriou
        $(window).trigger("resize");
303 4b997f54 Kostas Papadimitriou
      },
304 4b997f54 Kostas Papadimitriou
305 4b997f54 Kostas Papadimitriou
      handle_model_remove: function(model, collection, options) {
306 4b997f54 Kostas Papadimitriou
        this.remove_model(model);
307 4b997f54 Kostas Papadimitriou
      },
308 4b997f54 Kostas Papadimitriou
      
309 4b997f54 Kostas Papadimitriou
      show_empty: function() {
310 4b997f54 Kostas Papadimitriou
        this.empty_el.show();
311 4b997f54 Kostas Papadimitriou
      },
312 4b997f54 Kostas Papadimitriou
313 4b997f54 Kostas Papadimitriou
      hide_empty: function() {
314 4b997f54 Kostas Papadimitriou
        this.empty_el.hide();
315 4b997f54 Kostas Papadimitriou
      },
316 4b997f54 Kostas Papadimitriou
317 4b997f54 Kostas Papadimitriou
      check_empty: function() {
318 4b997f54 Kostas Papadimitriou
        if (this.collection.length == 0) {
319 4b997f54 Kostas Papadimitriou
          this.show_empty();
320 4b997f54 Kostas Papadimitriou
          this.list_el.hide();
321 4b997f54 Kostas Papadimitriou
        } else {
322 4b997f54 Kostas Papadimitriou
          this.list_el.show();
323 4b997f54 Kostas Papadimitriou
          this.hide_empty();
324 4b997f54 Kostas Papadimitriou
        }
325 4b997f54 Kostas Papadimitriou
      },
326 4b997f54 Kostas Papadimitriou
      
327 4b997f54 Kostas Papadimitriou
      parent_for_model: function(model) {
328 4b997f54 Kostas Papadimitriou
        return this.list_el;
329 4b997f54 Kostas Papadimitriou
      },
330 4b997f54 Kostas Papadimitriou
      
331 4b997f54 Kostas Papadimitriou
      place_in_parent: function(parent, el, m, index, anim) {
332 69dac1ba Kostas Papadimitriou
        var place_func, place_func_context, position_found, exists;
333 4b997f54 Kostas Papadimitriou
334 c700cb69 Kostas Papadimitriou
        _.each(parent.find(">.model-item"), function(el) {
335 4b997f54 Kostas Papadimitriou
          var el = $(el);
336 4b997f54 Kostas Papadimitriou
          var el_index = el.data('index');
337 4b997f54 Kostas Papadimitriou
          if (!el_index || position_found) { return };
338 4b997f54 Kostas Papadimitriou
          if (parseInt(el_index) < index) {
339 4b997f54 Kostas Papadimitriou
            place_func = el.before;
340 4b997f54 Kostas Papadimitriou
            place_func_context = el;
341 4b997f54 Kostas Papadimitriou
            position_found = true;
342 4b997f54 Kostas Papadimitriou
          }
343 4b997f54 Kostas Papadimitriou
        });
344 4b997f54 Kostas Papadimitriou
        
345 4b997f54 Kostas Papadimitriou
        if (!position_found) {
346 4b997f54 Kostas Papadimitriou
          place_func = parent.append;
347 4b997f54 Kostas Papadimitriou
          place_func_context = parent;
348 4b997f54 Kostas Papadimitriou
        }
349 4b997f54 Kostas Papadimitriou
350 4b997f54 Kostas Papadimitriou
        if (anim) {
351 4b997f54 Kostas Papadimitriou
          var self = this;
352 4b997f54 Kostas Papadimitriou
          el.fadeOut(this.animation_speed, function() {
353 4b997f54 Kostas Papadimitriou
            place_func.call(place_func_context, el);
354 4b997f54 Kostas Papadimitriou
            el.fadeIn(self.animation_speed);
355 4b997f54 Kostas Papadimitriou
          });
356 4b997f54 Kostas Papadimitriou
        } else {
357 4b997f54 Kostas Papadimitriou
          place_func.call(place_func_context, el);
358 4b997f54 Kostas Papadimitriou
        }
359 4b997f54 Kostas Papadimitriou
        el.attr("data-index", index);
360 4b997f54 Kostas Papadimitriou
      },
361 4b997f54 Kostas Papadimitriou
      
362 4b997f54 Kostas Papadimitriou
      get_model_view_cls: function(m) {
363 4b997f54 Kostas Papadimitriou
        return this.model_view_cls
364 4b997f54 Kostas Papadimitriou
      },
365 4b997f54 Kostas Papadimitriou
366 4b997f54 Kostas Papadimitriou
      add_model: function(m, index) {
367 4b997f54 Kostas Papadimitriou
        // if no available class for model exists, skip model add
368 4b997f54 Kostas Papadimitriou
        var view_cls = this.get_model_view_cls(m);
369 4b997f54 Kostas Papadimitriou
        if (!view_cls) { return }
370 4b997f54 Kostas Papadimitriou
        
371 4b997f54 Kostas Papadimitriou
        // avoid duplicate entries
372 4b997f54 Kostas Papadimitriou
        if (this._model_views[m.id]) { return }
373 4b997f54 Kostas Papadimitriou
        
374 4b997f54 Kostas Papadimitriou
        // handle empty collection
375 4b997f54 Kostas Papadimitriou
        this.check_empty();
376 4b997f54 Kostas Papadimitriou
        
377 4b997f54 Kostas Papadimitriou
        // initialize view
378 4b997f54 Kostas Papadimitriou
        var view = this.create_view(this.get_model_view_cls(m), {model: m});
379 4b997f54 Kostas Papadimitriou
        this.add_model_view(view, m, index);
380 4b997f54 Kostas Papadimitriou
      },
381 4b997f54 Kostas Papadimitriou
382 4b997f54 Kostas Papadimitriou
      add_model_view: function(view, model, index) {
383 4b997f54 Kostas Papadimitriou
        // append html element to the parent
384 4b997f54 Kostas Papadimitriou
        var el = view.init_element();
385 4b997f54 Kostas Papadimitriou
        // append to registry object
386 4b997f54 Kostas Papadimitriou
        this._model_views[model.id] = view;
387 4b997f54 Kostas Papadimitriou
        el.addClass("model-item");
388 4b997f54 Kostas Papadimitriou
        // where to place ?
389 4b997f54 Kostas Papadimitriou
        var parent = this.parent_for_model(model);
390 4b997f54 Kostas Papadimitriou
        // append
391 4b997f54 Kostas Papadimitriou
        this.place_in_parent(parent, el, model, index);
392 4b997f54 Kostas Papadimitriou
        // make it visible by default
393 4b997f54 Kostas Papadimitriou
        this.add_subview(view);
394 4b997f54 Kostas Papadimitriou
        view.show(true);
395 f9f43e09 Kostas Papadimitriou
        this.post_add_model_view(view, model);
396 4b997f54 Kostas Papadimitriou
      },
397 f9f43e09 Kostas Papadimitriou
      post_add_model_view: function() {},
398 f9f43e09 Kostas Papadimitriou
399 4b997f54 Kostas Papadimitriou
      each_model_view: function(cb, context) {
400 4b997f54 Kostas Papadimitriou
        if (!context) { context = this };
401 4b997f54 Kostas Papadimitriou
        _.each(this._model_views, function(view, model_id){
402 4b997f54 Kostas Papadimitriou
          var model = this.collection.get(model_id);
403 4b997f54 Kostas Papadimitriou
          cb.call(this, model, view, model_id);
404 4b997f54 Kostas Papadimitriou
        }, this);
405 4b997f54 Kostas Papadimitriou
      },
406 4b997f54 Kostas Papadimitriou
407 4b997f54 Kostas Papadimitriou
      remove_model: function(m) {
408 4b997f54 Kostas Papadimitriou
        var model_view = this._model_views[m.id];
409 4b997f54 Kostas Papadimitriou
        if (!model_view) {
410 4b997f54 Kostas Papadimitriou
          console.error("no view found");
411 4b997f54 Kostas Papadimitriou
          return;
412 4b997f54 Kostas Papadimitriou
        }
413 4b997f54 Kostas Papadimitriou
        model_view.hide();
414 4b997f54 Kostas Papadimitriou
        model_view.el.remove();
415 4b997f54 Kostas Papadimitriou
        this.remove_view(model_view);
416 32a58fdf Kostas Papadimitriou
        this.post_remove_model_view(model_view, m);
417 375a9cb5 Kostas Papadimitriou
        $(window).trigger("resize");
418 4b997f54 Kostas Papadimitriou
        delete this._model_views[m.id];
419 4b997f54 Kostas Papadimitriou
        this.check_empty();
420 4b997f54 Kostas Papadimitriou
      },
421 4b997f54 Kostas Papadimitriou
422 f9f43e09 Kostas Papadimitriou
      post_remove_model_view: function() {},
423 f9f43e09 Kostas Papadimitriou
424 4b997f54 Kostas Papadimitriou
      update_models: function(m) {
425 4b997f54 Kostas Papadimitriou
        this.check_empty();
426 4b997f54 Kostas Papadimitriou
        this.collection.each(function(model, index) {
427 4b997f54 Kostas Papadimitriou
          if (!(model.id in this._model_views)) {
428 4b997f54 Kostas Papadimitriou
            this.add_model(model, index);
429 4b997f54 Kostas Papadimitriou
          } else {
430 4b997f54 Kostas Papadimitriou
            if (model != this._model_views[model.id].model) {
431 4b997f54 Kostas Papadimitriou
              this._model_views[model.id].model = model;
432 4b997f54 Kostas Papadimitriou
              this._model_views[model.id].rivets_unbind();
433 4b997f54 Kostas Papadimitriou
              this._model_views[model.id].rivets_bind();
434 4b997f54 Kostas Papadimitriou
            }
435 4b997f54 Kostas Papadimitriou
            this.handle_model_change(model);
436 4b997f54 Kostas Papadimitriou
          }
437 4b997f54 Kostas Papadimitriou
        }, this);
438 4b997f54 Kostas Papadimitriou
        
439 4b997f54 Kostas Papadimitriou
        this.each_model_view(function(model, view, model_id){
440 4b997f54 Kostas Papadimitriou
          if (!model) {
441 4b997f54 Kostas Papadimitriou
            model = {'id': model_id};
442 4b997f54 Kostas Papadimitriou
            this.remove_model(model);
443 4b997f54 Kostas Papadimitriou
          }
444 4b997f54 Kostas Papadimitriou
        })
445 4b997f54 Kostas Papadimitriou
      }
446 4b997f54 Kostas Papadimitriou
    });
447 4b997f54 Kostas Papadimitriou
448 4b997f54 Kostas Papadimitriou
    views.ext.ModelView = views.ext.View.extend({
449 4b997f54 Kostas Papadimitriou
      rivets_view: true,
450 365af933 Kostas Papadimitriou
      
451 4b997f54 Kostas Papadimitriou
      initialize: function() {
452 4b997f54 Kostas Papadimitriou
        views.ext.ModelView.__super__.initialize.apply(this, arguments);
453 4b997f54 Kostas Papadimitriou
        var actions = this.model.get('actions');
454 4b997f54 Kostas Papadimitriou
        if (actions) {
455 4b997f54 Kostas Papadimitriou
          this.init_action_methods(this.model.get('actions'));
456 4b997f54 Kostas Papadimitriou
          this.bind("hide", function() {
457 4b997f54 Kostas Papadimitriou
            actions.reset_pending();
458 4b997f54 Kostas Papadimitriou
          });
459 4b997f54 Kostas Papadimitriou
        }
460 4b997f54 Kostas Papadimitriou
      },
461 4b997f54 Kostas Papadimitriou
      
462 bfb11987 Kostas Papadimitriou
      action_cls_map: {
463 bfb11987 Kostas Papadimitriou
        'remove': 'destroy'
464 bfb11987 Kostas Papadimitriou
      },
465 bfb11987 Kostas Papadimitriou
466 bfb11987 Kostas Papadimitriou
      _set_confirm: function(action) {
467 bfb11987 Kostas Papadimitriou
        this.pending_action = action;
468 bfb11987 Kostas Papadimitriou
        this.set_action_indicator(action);
469 bfb11987 Kostas Papadimitriou
      },
470 bfb11987 Kostas Papadimitriou
471 bfb11987 Kostas Papadimitriou
      _unset_confirm: function(action) {
472 bfb11987 Kostas Papadimitriou
        this.pending_action = undefined;
473 bfb11987 Kostas Papadimitriou
        this.reset_action_indicator(action);
474 bfb11987 Kostas Papadimitriou
      },
475 bfb11987 Kostas Papadimitriou
476 bfb11987 Kostas Papadimitriou
      set_action_indicator: function(action) {
477 bfb11987 Kostas Papadimitriou
        action = this.action_cls_map[action] || action;
478 bfb11987 Kostas Papadimitriou
        var indicator = this.el.find(".action-indicator");
479 bfb11987 Kostas Papadimitriou
        indicator = $(indicator[indicator.length - 1]);
480 bfb11987 Kostas Papadimitriou
        indicator.attr("class", "").addClass("state action-indicator " + action);
481 bfb11987 Kostas Papadimitriou
      },
482 bfb11987 Kostas Papadimitriou
483 bfb11987 Kostas Papadimitriou
      reset_action_indicator: function() {
484 bfb11987 Kostas Papadimitriou
        var indicator = this.el.find(".action-indicator");
485 bfb11987 Kostas Papadimitriou
        indicator = $(indicator[indicator.length - 1]);
486 bfb11987 Kostas Papadimitriou
        indicator.attr("class", "").addClass("state action-indicator");
487 bfb11987 Kostas Papadimitriou
        if (this.pending_action) {
488 bfb11987 Kostas Papadimitriou
          this.set_action_indicator(this.pending_action);
489 bfb11987 Kostas Papadimitriou
        }
490 bfb11987 Kostas Papadimitriou
      },
491 bfb11987 Kostas Papadimitriou
492 4b997f54 Kostas Papadimitriou
      set_confirm: function() {},
493 4b997f54 Kostas Papadimitriou
      unset_confirm: function() {},
494 4b997f54 Kostas Papadimitriou
495 4b997f54 Kostas Papadimitriou
      init_action_methods: function(actions) {
496 bfb11987 Kostas Papadimitriou
        var self = this;
497 bfb11987 Kostas Papadimitriou
        if (this.model && this.model.actions) {
498 bfb11987 Kostas Papadimitriou
          this.model.actions.bind("reset-pending", function() {
499 bfb11987 Kostas Papadimitriou
            this._unset_confirm();
500 bfb11987 Kostas Papadimitriou
          }, this);
501 bfb11987 Kostas Papadimitriou
          this.model.actions.bind("set-pending", function(action) {
502 bfb11987 Kostas Papadimitriou
            this._set_confirm(action)
503 bfb11987 Kostas Papadimitriou
          }, this);
504 bfb11987 Kostas Papadimitriou
        }
505 4b997f54 Kostas Papadimitriou
        _.each(actions.actions, function(action) {
506 bfb11987 Kostas Papadimitriou
          this.el.find(".action-container." + action).hover(function() {
507 bfb11987 Kostas Papadimitriou
            self.set_action_indicator(action);
508 bfb11987 Kostas Papadimitriou
          }, function() {
509 bfb11987 Kostas Papadimitriou
            self.reset_action_indicator();
510 bfb11987 Kostas Papadimitriou
          });
511 4b997f54 Kostas Papadimitriou
          var method;
512 4b997f54 Kostas Papadimitriou
          method = 'set_{0}_confirm'.format(action);
513 4b997f54 Kostas Papadimitriou
          if (this[method]) { return }
514 4b997f54 Kostas Papadimitriou
          this[method] = _.bind(function(model, ev) {
515 4b997f54 Kostas Papadimitriou
            if (ev) { ev.stopPropagation() }
516 4b997f54 Kostas Papadimitriou
            var data = {};
517 bfb11987 Kostas Papadimitriou
            this._set_confirm(action);
518 4b997f54 Kostas Papadimitriou
            this.set_confirm(action);
519 4b997f54 Kostas Papadimitriou
            this.model.actions.set_pending_action(action);
520 4b997f54 Kostas Papadimitriou
          }, this);
521 4b997f54 Kostas Papadimitriou
          method = 'unset_{0}_confirm'.format(action);
522 4b997f54 Kostas Papadimitriou
          if (this[method]) { return }
523 4b997f54 Kostas Papadimitriou
          this[method] = _.bind(function(model, ev) {
524 4b997f54 Kostas Papadimitriou
            if (ev) { ev.stopPropagation() }
525 4b997f54 Kostas Papadimitriou
            var data = {};
526 bfb11987 Kostas Papadimitriou
            this._unset_confirm(action);
527 4b997f54 Kostas Papadimitriou
            this.unset_confirm(action);
528 4b997f54 Kostas Papadimitriou
            this.model.actions.unset_pending_action(action);
529 4b997f54 Kostas Papadimitriou
          }, this);
530 4b997f54 Kostas Papadimitriou
        }, this);
531 4b997f54 Kostas Papadimitriou
      },
532 4b997f54 Kostas Papadimitriou
533 4b997f54 Kostas Papadimitriou
      get_rivet_object: function() {
534 4b997f54 Kostas Papadimitriou
        var model = {
535 4b997f54 Kostas Papadimitriou
          model: this.model
536 4b997f54 Kostas Papadimitriou
        }
537 4b997f54 Kostas Papadimitriou
        return model
538 4b997f54 Kostas Papadimitriou
      },
539 4b997f54 Kostas Papadimitriou
540 4b997f54 Kostas Papadimitriou
      post_init_element: function() {},
541 4b997f54 Kostas Papadimitriou
542 4b997f54 Kostas Papadimitriou
      init_element: function() {
543 4b997f54 Kostas Papadimitriou
        this.el.attr("id", "model-" + this.model.id);
544 4b997f54 Kostas Papadimitriou
        this.post_init_element();
545 4b997f54 Kostas Papadimitriou
        this.update_layout();
546 4b997f54 Kostas Papadimitriou
        return this.el;
547 4b997f54 Kostas Papadimitriou
      },
548 4b997f54 Kostas Papadimitriou
549 4b997f54 Kostas Papadimitriou
      update_layout: function() {}
550 4b997f54 Kostas Papadimitriou
551 4b997f54 Kostas Papadimitriou
    });
552 4b997f54 Kostas Papadimitriou
    
553 4b997f54 Kostas Papadimitriou
    views.ModelRenameView = views.ext.ModelView.extend({
554 4b997f54 Kostas Papadimitriou
      tpl: '#rename-view-tpl',
555 4b997f54 Kostas Papadimitriou
      title_attr: 'name',
556 4b997f54 Kostas Papadimitriou
557 4b997f54 Kostas Papadimitriou
      init: function() {
558 4b997f54 Kostas Papadimitriou
        views.ModelRenameView.__super__.init.apply(this, arguments);
559 4b997f54 Kostas Papadimitriou
        this.name_cont = this.$(".model-name");
560 4b997f54 Kostas Papadimitriou
        this.edit_cont = this.$(".edit");
561 4b997f54 Kostas Papadimitriou
562 4b997f54 Kostas Papadimitriou
        this.edit_btn = this.$(".edit-btn");
563 4b997f54 Kostas Papadimitriou
        this.value = this.$(".value");
564 4b997f54 Kostas Papadimitriou
        this.input = this.$("input");
565 4b997f54 Kostas Papadimitriou
        this.confirm = this.edit_cont.find(".confirm");
566 4b997f54 Kostas Papadimitriou
        this.cancel = this.edit_cont.find(".cancel");
567 4b997f54 Kostas Papadimitriou
        
568 4b997f54 Kostas Papadimitriou
        if (this.model.get('rename_disabled')) {
569 4b997f54 Kostas Papadimitriou
          this.edit_btn.remove();
570 4b997f54 Kostas Papadimitriou
        }
571 4b997f54 Kostas Papadimitriou
572 4b997f54 Kostas Papadimitriou
        this.value.dblclick(_.bind(function(e) {
573 4b997f54 Kostas Papadimitriou
          this.set_edit();
574 4b997f54 Kostas Papadimitriou
        }, this));
575 4b997f54 Kostas Papadimitriou
        this.input.bind('keyup', _.bind(function(e) {
576 4b997f54 Kostas Papadimitriou
          // enter keypress
577 4b997f54 Kostas Papadimitriou
          if (e.which == 13) { this.rename(); }
578 4b997f54 Kostas Papadimitriou
          // esc keypress
579 4b997f54 Kostas Papadimitriou
          if (e.which == 27) { this.unset_edit(); }
580 4b997f54 Kostas Papadimitriou
        }, this));
581 4b997f54 Kostas Papadimitriou
        // initial state
582 4b997f54 Kostas Papadimitriou
        this.unset_edit();
583 4b997f54 Kostas Papadimitriou
      },
584 4b997f54 Kostas Papadimitriou
      
585 4b997f54 Kostas Papadimitriou
      post_hide: function() {
586 4b997f54 Kostas Papadimitriou
        this.unset_edit();
587 4b997f54 Kostas Papadimitriou
      },
588 4b997f54 Kostas Papadimitriou
589 4b997f54 Kostas Papadimitriou
      set_edit: function() {
590 4b997f54 Kostas Papadimitriou
        if (this.model.get('rename_disabled')) { return }
591 4b997f54 Kostas Papadimitriou
        var self = this;
592 4b997f54 Kostas Papadimitriou
        this.input.val(this.model.get('name'));
593 4b997f54 Kostas Papadimitriou
        window.setTimeout(function() {
594 4b997f54 Kostas Papadimitriou
          self.input.focus();
595 4b997f54 Kostas Papadimitriou
        }, 20);
596 4b997f54 Kostas Papadimitriou
        this.name_cont.hide();
597 4b997f54 Kostas Papadimitriou
        this.edit_cont.show();
598 4b997f54 Kostas Papadimitriou
      },
599 4b997f54 Kostas Papadimitriou
600 4b997f54 Kostas Papadimitriou
      unset_edit: function() {
601 4b997f54 Kostas Papadimitriou
        this.name_cont.show();
602 4b997f54 Kostas Papadimitriou
        this.edit_cont.hide();
603 4b997f54 Kostas Papadimitriou
      },
604 4b997f54 Kostas Papadimitriou
605 4b997f54 Kostas Papadimitriou
      rename: function() {
606 4b997f54 Kostas Papadimitriou
        var value = _.trim(this.input.val());
607 4b997f54 Kostas Papadimitriou
        if (value) {
608 4b997f54 Kostas Papadimitriou
          this.model.rename(value);
609 4b997f54 Kostas Papadimitriou
          this.unset_edit();
610 4b997f54 Kostas Papadimitriou
        }
611 4b997f54 Kostas Papadimitriou
      }
612 4b997f54 Kostas Papadimitriou
    });
613 a37c5497 Kostas Papadimitriou
614 a37c5497 Kostas Papadimitriou
    views.ext.SelectModelView = views.ext.ModelView.extend({
615 a37c5497 Kostas Papadimitriou
      select: function() {
616 a37c5497 Kostas Papadimitriou
        if (!this.delegate_checked) {
617 a37c5497 Kostas Papadimitriou
          this.input.attr("checked", true);
618 a37c5497 Kostas Papadimitriou
          this.item.addClass("selected");
619 a37c5497 Kostas Papadimitriou
        }
620 a37c5497 Kostas Papadimitriou
        this.selected = true;
621 a37c5497 Kostas Papadimitriou
        this.trigger("change:select", this, this.selected);
622 a37c5497 Kostas Papadimitriou
      },
623 a37c5497 Kostas Papadimitriou
624 a37c5497 Kostas Papadimitriou
      deselect: function() {
625 a37c5497 Kostas Papadimitriou
        if (!this.delegate_checked) {
626 a37c5497 Kostas Papadimitriou
          this.input.attr("checked", false);
627 a37c5497 Kostas Papadimitriou
          this.item.removeClass("selected");
628 a37c5497 Kostas Papadimitriou
        }
629 a37c5497 Kostas Papadimitriou
        this.selected = false;
630 a37c5497 Kostas Papadimitriou
        this.trigger("change:select", this, this.selected);
631 a37c5497 Kostas Papadimitriou
      },
632 a37c5497 Kostas Papadimitriou
      
633 a37c5497 Kostas Papadimitriou
      toggle_select: function() {
634 a37c5497 Kostas Papadimitriou
        if (this.selected) { 
635 a37c5497 Kostas Papadimitriou
          this.deselect();
636 a37c5497 Kostas Papadimitriou
        } else {
637 a37c5497 Kostas Papadimitriou
          this.select();
638 a37c5497 Kostas Papadimitriou
        }
639 a37c5497 Kostas Papadimitriou
      },
640 a37c5497 Kostas Papadimitriou
641 a37c5497 Kostas Papadimitriou
      post_init_element: function() {
642 a37c5497 Kostas Papadimitriou
        this.input = $(this.$("input").get(0));
643 a37c5497 Kostas Papadimitriou
        this.item = $(this.$(".select-item").get(0));
644 a37c5497 Kostas Papadimitriou
        this.delegate_checked = this.model.get('noselect');
645 a37c5497 Kostas Papadimitriou
        this.deselect();
646 a37c5497 Kostas Papadimitriou
647 a37c5497 Kostas Papadimitriou
        var self = this;
648 a37c5497 Kostas Papadimitriou
        if (self.model.get('forced')) {
649 a37c5497 Kostas Papadimitriou
          this.select();
650 a37c5497 Kostas Papadimitriou
          this.input.attr("disabled", true);
651 a37c5497 Kostas Papadimitriou
          $(this.el).attr('title', this.forced_title);
652 a37c5497 Kostas Papadimitriou
          $(this.el).tooltip({
653 a37c5497 Kostas Papadimitriou
            'tipClass': 'tooltip', 
654 a37c5497 Kostas Papadimitriou
            'position': 'top center',
655 a37c5497 Kostas Papadimitriou
            'offset': [29, 0]
656 a37c5497 Kostas Papadimitriou
          });
657 a37c5497 Kostas Papadimitriou
        }
658 a37c5497 Kostas Papadimitriou
        
659 a37c5497 Kostas Papadimitriou
        $(this.item).click(function(e) {
660 a37c5497 Kostas Papadimitriou
          if (self.model.get('forced')) { return }
661 a37c5497 Kostas Papadimitriou
          e.stopPropagation();
662 a37c5497 Kostas Papadimitriou
          self.toggle_select();
663 a37c5497 Kostas Papadimitriou
        });
664 a37c5497 Kostas Papadimitriou
        
665 a37c5497 Kostas Papadimitriou
        views.ext.SelectModelView.__super__.post_init_element.apply(this,
666 a37c5497 Kostas Papadimitriou
                                                                    arguments);
667 a37c5497 Kostas Papadimitriou
      }
668 a37c5497 Kostas Papadimitriou
    });
669 a37c5497 Kostas Papadimitriou
670 4b997f54 Kostas Papadimitriou
    
671 4b997f54 Kostas Papadimitriou
    views.ext.ModelCreateView = views.ext.ModelView.extend({});
672 4b997f54 Kostas Papadimitriou
    views.ext.ModelEditView = views.ext.ModelCreateView.extend({});
673 4b997f54 Kostas Papadimitriou
674 4b997f54 Kostas Papadimitriou
})(this);