##// END OF EJS Templates
remove that.
Matthias Bussonnier -
Show More
@@ -1,302 +1,301 b''
1 1 // Copyright (c) IPython Development Team.
2 2 // Distributed under the terms of the Modified BSD License.
3 3
4 4 define([
5 5 "widgets/js/widget",
6 6 "base/js/utils",
7 7 "jquery",
8 8 "bootstrap",
9 9 ], function(widget, utils, $){
10 10
11 11 var AccordionView = widget.DOMWidgetView.extend({
12 12 initialize: function(){
13 13 AccordionView.__super__.initialize.apply(this, arguments);
14 14
15 15 this.containers = [];
16 16 this.model_containers = {};
17 17 this.children_views = new widget.ViewList(this.add_child_view, this.remove_child_view, this);
18 18 this.listenTo(this.model, 'change:children', function(model, value) {
19 19 this.children_views.update(value);
20 20 }, this);
21 21 },
22 22
23 23 render: function(){
24 24 /**
25 25 * Called when view is rendered.
26 26 */
27 27 var guid = 'panel-group' + utils.uuid();
28 28 this.$el
29 29 .attr('id', guid)
30 30 .addClass('panel-group');
31 31 this.model.on('change:selected_index', function(model, value, options) {
32 32 this.update_selected_index(model.previous('selected_index'), value, options);
33 33 }, this);
34 34 this.model.on('change:_titles', function(model, value, options) {
35 35 this.update_titles(value);
36 36 }, this);
37 var that = this;
38 37 this.on('displayed', function() {
39 38 this.update_titles();
40 39 }, this);
41 40 this.children_views.update(this.model.get('children'));
42 41 },
43 42
44 43 update_titles: function(titles) {
45 44 /**
46 45 * Set tab titles
47 46 */
48 47 if (!titles) {
49 48 titles = this.model.get('_titles');
50 49 }
51 50
52 51 var that = this;
53 52 _.each(titles, function(title, page_index) {
54 53 var accordian = that.containers[page_index];
55 54 if (accordian !== undefined) {
56 55 accordian
57 56 .find('.panel-heading')
58 57 .find('.accordion-toggle')
59 58 .text(title);
60 59 }
61 60 });
62 61 },
63 62
64 63 update_selected_index: function(old_index, new_index, options) {
65 64 /**
66 65 * Only update the selection if the selection wasn't triggered
67 66 * by the front-end. It must be triggered by the back-end.
68 67 */
69 68 if (options === undefined || options.updated_view != this) {
70 69 this.containers[old_index].find('.panel-collapse').collapse('hide');
71 70 if (0 <= new_index && new_index < this.containers.length) {
72 71 this.containers[new_index].find('.panel-collapse').collapse('show');
73 72 }
74 73 }
75 74 },
76 75
77 76 remove_child_view: function(view) {
78 77 /**
79 78 * Called when a child is removed from children list.
80 79 * TODO: does this handle two different views of the same model as children?
81 80 */
82 81 var model = view.model;
83 82 var accordion_group = this.model_containers[model.id];
84 83 this.containers.splice(accordion_group.container_index, 1);
85 84 delete this.model_containers[model.id];
86 85 accordion_group.remove();
87 86 },
88 87
89 88 add_child_view: function(model) {
90 89 /**
91 90 * Called when a child is added to children list.
92 91 */
93 92 var index = this.containers.length;
94 93 var uuid = utils.uuid();
95 94 var accordion_group = $('<div />')
96 95 .addClass('panel panel-default')
97 96 .appendTo(this.$el);
98 97 var accordion_heading = $('<div />')
99 98 .addClass('panel-heading')
100 99 .appendTo(accordion_group);
101 100 var that = this;
102 101 var accordion_toggle = $('<a />')
103 102 .addClass('accordion-toggle')
104 103 .attr('data-toggle', 'collapse')
105 104 .attr('data-parent', '#' + this.$el.attr('id'))
106 105 .attr('href', '#' + uuid)
107 106 .click(function(evt){
108 107
109 108 // Calling model.set will trigger all of the other views of the
110 109 // model to update.
111 110 that.model.set("selected_index", index, {updated_view: that});
112 111 that.touch();
113 112 })
114 113 .text('Page ' + index)
115 114 .appendTo(accordion_heading);
116 115 var accordion_body = $('<div />', {id: uuid})
117 116 .addClass('panel-collapse collapse')
118 117 .appendTo(accordion_group);
119 118 var accordion_inner = $('<div />')
120 119 .addClass('panel-body')
121 120 .appendTo(accordion_body);
122 121 var container_index = this.containers.push(accordion_group) - 1;
123 122 accordion_group.container_index = container_index;
124 123 this.model_containers[model.id] = accordion_group;
125 124
126 125 var dummy = $('<div/>');
127 126 accordion_inner.append(dummy);
128 127 return this.create_child_view(model).then(function(view) {
129 128 dummy.replaceWith(view.$el);
130 129 that.update();
131 130 that.update_titles();
132 131
133 132 // Trigger the displayed event of the child view.
134 133 that.after_displayed(function() {
135 134 view.trigger('displayed');
136 135 });
137 136 return view;
138 137 }).catch(utils.reject("Couldn't add child view to box", true));
139 138 },
140 139
141 140 remove: function() {
142 141 /**
143 142 * We remove this widget before removing the children as an optimization
144 143 * we want to remove the entire container from the DOM first before
145 144 * removing each individual child separately.
146 145 */
147 146 AccordionView.__super__.remove.apply(this, arguments);
148 147 this.children_views.remove();
149 148 },
150 149 });
151 150
152 151
153 152 var TabView = widget.DOMWidgetView.extend({
154 153 initialize: function() {
155 154 /**
156 155 * Public constructor.
157 156 */
158 157 TabView.__super__.initialize.apply(this, arguments);
159 158
160 159 this.containers = [];
161 160 this.children_views = new widget.ViewList(this.add_child_view, this.remove_child_view, this);
162 161 this.listenTo(this.model, 'change:children', function(model, value) {
163 162 this.children_views.update(value);
164 163 }, this);
165 164 },
166 165
167 166 render: function(){
168 167 /**
169 168 * Called when view is rendered.
170 169 */
171 170 var uuid = 'tabs'+utils.uuid();
172 171 var that = this;
173 172 this.$tabs = $('<div />', {id: uuid})
174 173 .addClass('nav')
175 174 .addClass('nav-tabs')
176 175 .appendTo(this.$el);
177 176 this.$tab_contents = $('<div />', {id: uuid + 'Content'})
178 177 .addClass('tab-content')
179 178 .appendTo(this.$el);
180 179 this.children_views.update(this.model.get('children'));
181 180 },
182 181
183 182 update_attr: function(name, value) {
184 183 /**
185 184 * Set a css attr of the widget view.
186 185 */
187 186 if (name == 'padding' || name == 'margin') {
188 187 this.$el.css(name, value);
189 188 } else {
190 189 this.$tabs.css(name, value);
191 190 }
192 191 },
193 192
194 193 remove_child_view: function(view) {
195 194 /**
196 195 * Called when a child is removed from children list.
197 196 */
198 197 this.containers.splice(view.parent_tab.tab_text_index, 1);
199 198 view.parent_tab.remove();
200 199 view.parent_container.remove();
201 200 view.remove();
202 201 },
203 202
204 203 add_child_view: function(model) {
205 204 /**
206 205 * Called when a child is added to children list.
207 206 */
208 207 var index = this.containers.length;
209 208 var uuid = utils.uuid();
210 209
211 210 var that = this;
212 211 var tab = $('<li />')
213 212 .css('list-style-type', 'none')
214 213 .appendTo(this.$tabs);
215 214
216 215
217 216 var tab_text = $('<a />')
218 217 .attr('href', '#' + uuid)
219 218 .attr('data-toggle', 'tab')
220 219 .text('Page ' + index)
221 220 .appendTo(tab)
222 221 .click(function (e) {
223 222
224 223 // Calling model.set will trigger all of the other views of the
225 224 // model to update.
226 225 that.model.set("selected_index", index, {updated_view: that});
227 226 that.touch();
228 227 that.select_page(index);
229 228 });
230 229 tab.tab_text_index = that.containers.push(tab_text) - 1;
231 230
232 231 var dummy = $('<div />');
233 232 var contents_div = $('<div />', {id: uuid})
234 233 .addClass('tab-pane')
235 234 .addClass('fade')
236 235 .append(dummy)
237 236 .appendTo(that.$tab_contents);
238 237
239 238 return this.create_child_view(model).then(function(view) {
240 239 dummy.replaceWith(view.$el);
241 240 view.parent_tab = tab;
242 241 view.parent_container = contents_div;
243 242
244 243 // Trigger the displayed event of the child view.
245 244 that.after_displayed(function() {
246 245 view.trigger('displayed');
247 246 });
248 247 return view;
249 248 }).catch(utils.reject("Couldn't add child view to box", true));
250 249 },
251 250
252 251 update: function(options) {
253 252 /**
254 253 * Update the contents of this view
255 254 *
256 255 * Called when the model is changed. The model may have been
257 256 * changed by another view or by a state update from the back-end.
258 257 */
259 258 if (options === undefined || options.updated_view != this) {
260 259 // Set tab titles
261 260 var titles = this.model.get('_titles');
262 261 var that = this;
263 262 _.each(titles, function(title, page_index) {
264 263 var tab_text = that.containers[page_index];
265 264 if (tab_text !== undefined) {
266 265 tab_text.text(title);
267 266 }
268 267 });
269 268
270 269 var selected_index = this.model.get('selected_index');
271 270 if (0 <= selected_index && selected_index < this.containers.length) {
272 271 this.select_page(selected_index);
273 272 }
274 273 }
275 274 return TabView.__super__.update.apply(this);
276 275 },
277 276
278 277 select_page: function(index) {
279 278 /**
280 279 * Select a page.
281 280 */
282 281 this.$tabs.find('li')
283 282 .removeClass('active');
284 283 this.containers[index].tab('show');
285 284 },
286 285
287 286 remove: function() {
288 287 /**
289 288 * We remove this widget before removing the children as an optimization
290 289 * we want to remove the entire container from the DOM first before
291 290 * removing each individual child separately.
292 291 */
293 292 TabView.__super__.remove.apply(this, arguments);
294 293 this.children_views.remove();
295 294 },
296 295 });
297 296
298 297 return {
299 298 'AccordionView': AccordionView,
300 299 'TabView': TabView,
301 300 };
302 301 });
General Comments 0
You need to be logged in to leave comments. Login now