smartxml: Getting rid of nodeMoved event in favor of `move` flag on nodeDetached...
[fnpeditor.git] / src / editor / views / tabs / tabs.js
1 define([
2 'libs/jquery',
3 'libs/text!./templates/main.html',
4 'libs/text!./templates/handle.html',
5 'libs/underscore',
6 'libs/backbone'
7 ], function($, mainTemplate, handleTemplate, _, Backbone) {
8     'use strict';
9     
10     var View = Backbone.View.extend({
11         className: 'rng-view-tabs',
12         
13         events: {
14             'click .rng-view-tabs-tabBar a, .rng-view-tabs-tabBar i': '_onTabTitleClicked'
15         },
16         
17         initialize: function(options) {
18             this.options = options || {};
19             this.template = _.template(mainTemplate);
20             this.handleTemplate = _.template(handleTemplate);
21             this.contents = {};
22             this.selectedTab = null;
23         },
24         
25         render: function() {
26             this.$el.html(this.template());
27             this.nodes = {
28                 tabBar: this.$('.rng-view-tabs-tabBar'),
29                 content: this.$('.rng-view-tabs-content')
30             };
31             
32             if(this.options.stacked) {
33                 this.nodes.tabBar.addClass('nav-stacked nav-pills').removeClass('nav-tabs');
34             }
35             if(this.options.position === 'right') {
36                 this.$el.addClass('tabs-right');
37                 this.nodes.content.addClass('tab-content');
38             }
39             return this;
40         },
41         
42         addTab: function(title, slug, content) {
43             if(this.contents[slug]) {
44                 this.contents[slug].detach();
45             }
46             this.contents[slug] = content;
47             
48             var text = (typeof title === 'string') ? title : (title.text || '');
49             var icon = title.icon || null;
50             
51             if(!this.tabExists(slug)) {
52                 this.nodes.tabBar.append(this.handleTemplate({text: text, icon: icon, slug: slug}));
53             }
54             if(!this.selectedTab) {
55                 this.selectTab(slug);
56             }
57         },
58         
59         selectTab: function(slug) {
60             if(slug !== this.selectedTab && this.contents[slug]) {
61                 this.trigger('leaving', this.selectedTab);
62                 
63                 if(this.selectedTab) {
64                     var toDetach = this.contents[this.selectedTab];
65                     if(toDetach.onHide) {
66                         toDetach.onHide();
67                     }
68                     toDetach.detach();
69                 }
70                 this.nodes.content.append(this.contents[slug]);
71                 if(this.contents[slug].onShow) {
72                     this.contents[slug].onShow();
73                 }
74                 this.nodes.tabBar.find('.active').removeClass('active');
75                 this.nodes.tabBar.find('a[href="#'+slug+'"]').parent().addClass('active');
76                 
77                 var prevSlug = this.selectedTab;
78                 this.selectedTab = slug;
79                 this.trigger('tabSelected', {slug: slug, prevSlug: prevSlug});
80             }
81         },
82         
83         getAsView: function() {
84             return this.$el;
85         },
86         
87         getCurrentSlug: function() {
88             return this.selectedTab;
89         },
90         
91         tabExists: function(slug) {
92             return this.nodes.tabBar.find('a[href="#'+ slug + '"]').length > 0;
93         },
94         
95         /* Events */
96         
97         _onTabTitleClicked: function(e) {
98             e.preventDefault();
99             var target = $(e.target);
100             if(target.is('i')) {
101                 target = target.parent();
102             }
103             var slug = target.attr('href').substr(1);
104             this.selectTab(slug);
105         }
106     });
107
108     
109     return {
110         View: View
111     };
112     
113
114 });