Revision 198b546d snf-cyclades-app/synnefo/ui/static/snf/js/views_ext.js

b/snf-cyclades-app/synnefo/ui/static/snf/js/views_ext.js
1
// Copyright 2014 GRNET S.A. All rights reserved.
2
// 
3
// Redistribution and use in source and binary forms, with or
4
// without modification, are permitted provided that the following
5
// conditions are met:
6
// 
7
//   1. Redistributions of source code must retain the above
8
//      copyright notice, this list of conditions and the following
9
//      disclaimer.
10
// 
11
//   2. Redistributions in binary form must reproduce the above
12
//      copyright notice, this list of conditions and the following
13
//      disclaimer in the documentation and/or other materials
14
//      provided with the distribution.
15
// 
16
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
// POSSIBILITY OF SUCH DAMAGE.
28
// 
29
// The views and conclusions contained in the software and
30
// documentation are those of the authors and should not be
31
// interpreted as representing official policies, either expressed
32
// or implied, of GRNET S.A.
33
// 
34

  
1 35
;(function(root){
2 36
    
3 37
    // root
......
39 73
        this.container = options && options.container;
40 74
        this._subviews = [];
41 75
        if (this.tpl) {
42
          this.el = $(this.tpl).clone().removeClass("hidden").removeAttr('id');
76
          var tpl = $(this.tpl);
77
          if (tpl.hasClass("inner-tpl")) { tpl = tpl.children().get(0); }
78
          this.el = $(tpl).clone().removeClass("hidden").removeAttr('id');
43 79
        }
44 80
        this.init.apply(this, arguments);
45 81
        this.post_init.apply(this, arguments);
......
53 89
        var cont = $(this.container);
54 90
        cont.append(this.el);
55 91
      },
56

  
92
      
57 93
      create_view: function(view_cls, options) {
58 94
        var options = _.extend({}, options);
59 95
        options.parent_view = this;
......
203 239
      animation_speed: 200,
204 240
      quota_key: undefined,
205 241
      quota_limit_message: undefined,
206

  
242
      list_el_selector: '.items-list',
207 243
      init: function() {
208 244
        var handlers = {};
209 245
        handlers[this.collection_name] = {
......
217 253
        this._model_views = {};
218 254
        this.list_el = $(this.$(".items-list").get(0));
219 255
        this.empty_el = $(this.$(".empty-list").get(0));
256
        if (this._id) { debugger }
220 257
        if (this.create_view_cls) {
221 258
          this._create_view = new this.create_view_cls();
222 259
          this._create_view.parent_view = this;
......
231 268
          this.handle_create_click();
232 269
        }, this));
233 270
        
234
        if (this.quota_key && !this.quota) {
235
          this.quota = synnefo.storage.quotas.get(this.quota_key);
236
        }
237

  
238
        if (this.quota) {
239
          this.quota.bind("change", _.bind(this.update_quota, this));
271
        if (this.quota_key) {
272
          synnefo.storage.quotas.bind("change", 
273
                                      _.bind(this.update_quota, this));
240 274
          this.update_quota();
241 275
        }
242 276
      },
243 277
      
244 278
      update_quota: function() {
245
        var available = this.quota.get_available();
246
        if (available > 0) {
279
        var can_create = synnefo.storage.quotas.can_create(this.quota_key);
280
        if (can_create) {
247 281
          this.create_button.removeClass("disabled");
248 282
          this.create_button.attr("title", "");
249 283
        } else {
250 284
          this.create_button.addClass("disabled");
251
          this.create_button.attr("title", this.quota_limit_message || "Quota limit reached")
285
          this.create_button.attr("title", 
286
                                  this.quota_limit_message || "Quota limit reached")
252 287
        }
253 288
      },
254 289
      
255
      post_create: function() {
256
        this.quota && this.quota.increase();
257
      },
258

  
259
      post_destroy: function() {
260
        this.quota && this.quota.decrease();
261
      },
262

  
263 290
      handle_create_click: function() {
264 291
        if (this.create_button.hasClass("disabled")) { return }
265 292

  
......
267 294
          this._create_view.show();
268 295
        }
269 296
      },
297
      
298
      post_hide: function() {
299
        this.each_model_view(function(model, view) {
300
          this.unbind_custom_view_handlers(view, model);
301
        }, this);
302
        views.ext.CollectionView.__super__.pre_hide.apply(this, arguments);
303
      },
270 304

  
271 305
      pre_show: function() {
306
        this.each_model_view(function(model, view) {
307
          this.bind_custom_view_handlers(view, model);
308
        }, this);
272 309
        views.ext.CollectionView.__super__.pre_show.apply(this, arguments);
273 310
        this.update_models();
274 311
      },
......
362 399
      get_model_view_cls: function(m) {
363 400
        return this.model_view_cls
364 401
      },
402
      
403
      model_view_options: function(m) { return {} },
365 404

  
366 405
      add_model: function(m, index) {
367 406
        // if no available class for model exists, skip model add
......
375 414
        this.check_empty();
376 415
        
377 416
        // initialize view
378
        var view = this.create_view(this.get_model_view_cls(m), {model: m});
417
        var model_view_options = {model: m}
418
        var extra_options = this.model_view_options(m);
419
        _.extend(model_view_options, extra_options);
420
        var view = this.create_view(this.get_model_view_cls(m),
421
                                    model_view_options);
379 422
        this.add_model_view(view, m, index);
380 423
      },
381 424

  
......
393 436
        this.add_subview(view);
394 437
        view.show(true);
395 438
        this.post_add_model_view(view, model);
439
        this.bind_custom_view_handlers(view, model);
396 440
      },
441

  
397 442
      post_add_model_view: function() {},
398 443

  
399 444
      each_model_view: function(cb, context) {
......
413 458
        model_view.hide();
414 459
        model_view.el.remove();
415 460
        this.remove_view(model_view);
461
        this.unbind_custom_view_handlers(model_view, m);
416 462
        this.post_remove_model_view(model_view, m);
417 463
        $(window).trigger("resize");
418 464
        delete this._model_views[m.id];
419 465
        this.check_empty();
420 466
      },
421

  
467
      
468
      bind_custom_view_handlers: function(view, model) {},
469
      unbind_custom_view_handlers: function(view, model) {},
422 470
      post_remove_model_view: function() {},
423 471

  
424 472
      update_models: function(m) {
......
445 493
      }
446 494
    });
447 495

  
496
    views.ext.CollectionSelectView = views.ext.CollectionView.extend({
497
      allow_multiple: false,
498
      initialize: function(options) {
499
        views.ext.CollectionSelectView.__super__.initialize.apply(this, [options]);
500
        this.allow_multiple = options.allow_multiple != undefined ? options.allow_multiple : this.allow_multiple;
501
        this.current = options.current != undefined ? options.current : undefined;
502
      },
503

  
504
      select: function(model) {
505
        if (!this.allow_multiple) {
506
          this.deselect_all();
507
        }
508
        this._model_views[model.id].select();
509
      },
510

  
511
      deselect: function(model) {
512
        this._model_views[model.id].deselect();
513
      },
514

  
515
      deselect_all: function(model) {
516
        _.each(this._model_views, function(view) {
517
          view.deselect();
518
        })
519
      },    
520
      
521
      get_selected: function() {
522
        var models = _.map(this._model_views, function(view) {
523
          if (view.selected) { 
524
            return view.model
525
          }
526
        });
527
        return _.filter(models, function(m) { return m });
528
      },
529
      
530
      handle_click: function(view) {
531
        if (!view.selected && !view.disabled) {
532
          if (!this.allow_multiple) {
533
            this.deselect_all();
534
          }
535
        }
536
      },
537

  
538
      post_add_model_view: function(view, model) {
539
        view.bind('click', function() {
540
          this.handle_click(view);
541
        }, this);
542

  
543
        view.bind('selected', function(view) {
544
          if (this.current != view.model) {
545
            this.current = view.model;
546
            this.trigger("change", this.get_selected());
547
          }
548
        }, this);
549
      },
550

  
551
      set_current: function(model) {
552
        this._model_views[model.id].select();
553
      }
554

  
555
    });
556

  
448 557
    views.ext.ModelView = views.ext.View.extend({
449 558
      rivets_view: true,
450 559
      
......
612 721
    });
613 722

  
614 723
    views.ext.SelectModelView = views.ext.ModelView.extend({
724
      can_deselect: true,
615 725
      select: function() {
616 726
        if (!this.delegate_checked) {
617 727
          this.input.attr("checked", true);
618 728
          this.item.addClass("selected");
729
          this.item.attr("selected", true);
619 730
        }
620 731
        this.selected = true;
621 732
        this.trigger("change:select", this, this.selected);
733
        this.trigger("selected", this, this.selected);
734
        this.parent_view && this.parent_view.trigger("change:select", this, this.selected);
622 735
      },
623 736

  
624 737
      deselect: function() {
625 738
        if (!this.delegate_checked) {
626 739
          this.input.attr("checked", false);
627 740
          this.item.removeClass("selected");
741
          this.item.attr("selected", false);
628 742
        }
629 743
        this.selected = false;
630 744
        this.trigger("change:select", this, this.selected);
745
        this.trigger("deselected", this, this.selected);
746
        this.parent_view && this.parent_view.trigger("change:select", this, this.selected);
631 747
      },
632 748
      
633 749
      toggle_select: function() {
750
        if (!this.can_deselect) {
751
          this.select();
752
          return;
753
        }
634 754
        if (this.selected) { 
635 755
          this.deselect();
636 756
        } else {
......
641 761
      post_init_element: function() {
642 762
        this.input = $(this.$("input").get(0));
643 763
        this.item = $(this.$(".select-item").get(0));
764
        if (!this.item.length) {
765
          this.item = $(this.el);
766
        }
644 767
        this.delegate_checked = this.model.get('noselect');
645 768
        this.deselect();
646 769

  
......
657 780
        }
658 781
        
659 782
        $(this.item).click(function(e) {
783
          self.trigger('click');
660 784
          if (self.model.get('forced')) { return }
785
          if (self.input.attr('disabled')) { return }
786
          if (self.disabled) { return }
661 787
          e.stopPropagation();
662 788
          self.toggle_select();
663 789
        });
664 790
        
665 791
        views.ext.SelectModelView.__super__.post_init_element.apply(this,
666 792
                                                                    arguments);
793
      },
794

  
795
      set_disabled: function() {
796
        this.disabled = true;
797
        this.input.attr("disabled", true);
798
        this.item.addClass("disabled");
799
        this.item.attr("disabled", true);
800
      },
801

  
802
      set_enabled: function() {
803
        this.disabled = false;
804
        this.input.attr("disabled", false);
805
        this.item.removeClass("disabled");
806
        this.item.attr("disabled", false);
667 807
      }
808

  
668 809
    });
669 810

  
670
    
671 811
    views.ext.ModelCreateView = views.ext.ModelView.extend({});
672 812
    views.ext.ModelEditView = views.ext.ModelCreateView.extend({});
673 813

  

Also available in: Unified diff