##// END OF EJS Templates
Fixed bug that prevented popup widget from displaying
Jonathan Frederic -
Show More
@@ -1,272 +1,274
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2013 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // ContainerWidget
10 10 //============================================================================
11 11
12 12 /**
13 13 * @module IPython
14 14 * @namespace IPython
15 15 **/
16 16
17 17 define(["notebook/js/widgets/widget"], function(WidgetManager) {
18 18
19 19 var ContainerView = IPython.DOMWidgetView.extend({
20 20 render: function(){
21 21 // Called when view is rendered.
22 22 this.$el
23 23 .addClass('widget-container');
24 24 this.children={};
25 25 this.update_children([], this.model.get('_children'));
26 26 this.model.on('change:_children', function(model, value, options) {
27 27 this.update_children(model.previous('_children'), value);
28 28 }, this);
29 29 this.update()
30 30 },
31 31
32 32 update_children: function(old_list, new_list) {
33 33 // Called when the children list changes.
34 34 this.do_diff(old_list,
35 35 new_list,
36 36 $.proxy(this.remove_child_model, this),
37 37 $.proxy(this.add_child_model, this));
38 38 },
39 39
40 40 remove_child_model: function(model) {
41 41 // Called when a model is removed from the children list.
42 42 this.child_views[model.id].remove();
43 43 this.delete_child_view(model);
44 44 },
45 45
46 46 add_child_model: function(model) {
47 47 // Called when a model is added to the children list.
48 48 var view = this.create_child_view(model);
49 49 this.$el.append(view.$el);
50 50 },
51 51
52 52 update: function(){
53 53 // Update the contents of this view
54 54 //
55 55 // Called when the model is changed. The model may have been
56 56 // changed by another view or by a state update from the back-end.
57 57 return ContainerView.__super__.update.apply(this);
58 58 },
59 59 });
60 60 WidgetManager.register_widget_view('ContainerView', ContainerView);
61 61
62 62
63 63 var PopupView = IPython.DOMWidgetView.extend({
64 64 render: function(){
65 65 // Called when view is rendered.
66 66 var that = this;
67 67 this.children={};
68 this.update_children([], this.model.get('_children'));
69 this.model.on('change:_children', function(model, value, options) {
70 this.update_children(model.previous('_children'), value);
71 }, this);
72 68
73 69 this.$el
74 70 .on("remove", function(){
75 71 that.$window.remove();
76 72 });
77 73 this.$window = $('<div />')
78 74 .addClass('modal widget-modal')
79 75 .appendTo($('#notebook-container'))
80 76 .mousedown(function(){
81 77 that.bring_to_front();
82 78 });
83 79 this.$title_bar = $('<div />')
84 80 .addClass('popover-title')
85 81 .appendTo(this.$window)
86 82 .mousedown(function(){
87 83 that.bring_to_front();
88 84 });
89 85 this.$close = $('<button />')
90 86 .addClass('close icon-remove')
91 87 .css('margin-left', '5px')
92 88 .appendTo(this.$title_bar)
93 89 .click(function(){
94 90 that.hide();
95 91 event.stopPropagation();
96 92 });
97 93 this.$minimize = $('<button />')
98 94 .addClass('close icon-arrow-down')
99 95 .appendTo(this.$title_bar)
100 96 .click(function(){
101 97 that.popped_out = !that.popped_out;
102 98 if (!that.popped_out) {
103 99 that.$minimize
104 100 .removeClass('icon-arrow-down')
105 101 .addClass('icon-arrow-up');
106 102
107 103 that.$window
108 104 .draggable('destroy')
109 105 .resizable('destroy')
110 106 .removeClass('widget-modal modal')
111 107 .addClass('docked-widget-modal')
112 108 .detach()
113 109 .insertBefore(that.$show_button);
114 110 that.$show_button.hide();
115 111 that.$close.hide();
116 112 } else {
117 113 that.$minimize
118 114 .addClass('icon-arrow-down')
119 115 .removeClass('icon-arrow-up');
120 116
121 117 that.$window
122 118 .removeClass('docked-widget-modal')
123 119 .addClass('widget-modal modal')
124 120 .detach()
125 121 .appendTo($('#notebook-container'))
126 122 .draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'})
127 123 .resizable()
128 124 .children('.ui-resizable-handle').show();
129 125 that.show();
130 126 that.$show_button.show();
131 127 that.$close.show();
132 128 }
133 129 event.stopPropagation();
134 130 });
135 131 this.$title = $('<div />')
136 132 .addClass('widget-modal-title')
137 133 .text(' ')
138 134 .appendTo(this.$title_bar);
139 135 this.$body = $('<div />')
140 136 .addClass('modal-body')
141 137 .addClass('widget-modal-body')
142 138 .addClass('widget-container')
143 139 .appendTo(this.$window);
144 140
145 141 this.$show_button = $('<button />')
146 142 .text(' ')
147 143 .addClass('btn btn-info widget-modal-show')
148 144 .appendTo(this.$el)
149 145 .click(function(){
150 146 that.show();
151 147 });
152 148
153 149 this.$window.draggable({handle: '.popover-title', snap: '#notebook, .modal', snapMode: 'both'});
154 150 this.$window.resizable();
155 151 this.$window.on('resize', function(){
156 152 that.$body.outerHeight(that.$window.innerHeight() - that.$title_bar.outerHeight());
157 153 });
158 154
159 155 this.$el_to_style = this.$body;
160 156 this._shown_once = false;
161 157 this.popped_out = true;
158
159 this.update_children([], this.model.get('_children'));
160 this.model.on('change:_children', function(model, value, options) {
161 this.update_children(model.previous('_children'), value);
162 }, this);
163 this.update();
162 164 },
163 165
164 166 hide: function() {
165 167 // Called when the modal hide button is clicked.
166 168 this.$window.hide();
167 169 this.$show_button.removeClass('btn-info');
168 170 },
169 171
170 172 show: function() {
171 173 // Called when the modal show button is clicked.
172 174 this.$show_button.addClass('btn-info');
173 175 this.$window.show();
174 176 if (this.popped_out) {
175 177 this.$window.css("positon", "absolute");
176 178 this.$window.css("top", "0px");
177 179 this.$window.css("left", Math.max(0, (($('body').outerWidth() - this.$window.outerWidth()) / 2) +
178 180 $(window).scrollLeft()) + "px");
179 181 this.bring_to_front();
180 182 }
181 183 },
182 184
183 185 bring_to_front: function() {
184 186 // Make the modal top-most, z-ordered about the other modals.
185 187 var $widget_modals = $(".widget-modal");
186 188 var max_zindex = 0;
187 189 $widget_modals.each(function (index, el){
188 190 max_zindex = Math.max(max_zindex, parseInt($(el).css('z-index')));
189 191 });
190 192
191 193 // Start z-index of widget modals at 2000
192 194 max_zindex = Math.max(max_zindex, 2000);
193 195
194 196 $widget_modals.each(function (index, el){
195 197 $el = $(el);
196 198 if (max_zindex == parseInt($el.css('z-index'))) {
197 199 $el.css('z-index', max_zindex - 1);
198 200 }
199 201 });
200 202 this.$window.css('z-index', max_zindex);
201 203 },
202 204
203 205 update_children: function(old_list, new_list) {
204 206 // Called when the children list is modified.
205 207 this.do_diff(old_list,
206 208 new_list,
207 209 $.proxy(this.remove_child_model, this),
208 210 $.proxy(this.add_child_model, this));
209 211 },
210 212
211 213 remove_child_model: function(model) {
212 214 // Called when a child is removed from children list.
213 215 this.child_views[model.id].remove();
214 216 this.delete_child_view(model);
215 217 },
216 218
217 219 add_child_model: function(model) {
218 220 // Called when a child is added to children list.
219 221 var view = this.create_child_view(model);
220 222 this.$body.append(view.$el);
221 223 },
222 224
223 225 update: function(){
224 226 // Update the contents of this view
225 227 //
226 228 // Called when the model is changed. The model may have been
227 229 // changed by another view or by a state update from the back-end.
228 230 var description = this.model.get('description');
229 231 if (description.length === 0) {
230 232 this.$title.text(' '); // Preserve title height
231 233 } else {
232 234 this.$title.text(description);
233 235 }
234 236
235 237 var button_text = this.model.get('button_text');
236 238 if (button_text.length === 0) {
237 239 this.$show_button.text(' '); // Preserve button height
238 240 } else {
239 241 this.$show_button.text(button_text);
240 242 }
241 243
242 244 if (!this._shown_once) {
243 245 this._shown_once = true;
244 246 this.show();
245 247 }
246 248
247 249 return PopupView.__super__.update.apply(this);
248 250 },
249 251
250 252 _get_selector_element: function(selector) {
251 253 // Get an element view a 'special' jquery selector. (see widget.js)
252 254 //
253 255 // Since the modal actually isn't within the $el in the DOM, we need to extend
254 256 // the selector logic to allow the user to set css on the modal if need be.
255 257 // The convention used is:
256 258 // "modal" - select the modal div
257 259 // "modal [selector]" - select element(s) within the modal div.
258 260 // "[selector]" - select elements within $el
259 261 // "" - select the $el_to_style
260 262 if (selector.substring(0, 5) == 'modal') {
261 263 if (selector == 'modal') {
262 264 return this.$window;
263 265 } else {
264 266 return this.$window.find(selector.substring(6));
265 267 }
266 268 } else {
267 269 return PopupView.__super__._get_selector_element.apply(this, [selector]);
268 270 }
269 271 },
270 272 });
271 273 WidgetManager.register_widget_view('PopupView', PopupView);
272 274 });
General Comments 0
You need to be logged in to leave comments. Login now