##// END OF EJS Templates
slightly generalize utils generator
Matthias BUSSONNIER -
Show More
@@ -1,353 +1,349 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2012 The IPython Development Team
2 // Copyright (C) 2012 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // CellToolbar
9 // CellToolbar
10 //============================================================================
10 //============================================================================
11
11
12
12
13 /**
13 /**
14 * A Module to control the per-cell toolbar.
14 * A Module to control the per-cell toolbar.
15 * @module IPython
15 * @module IPython
16 * @namespace IPython
16 * @namespace IPython
17 * @submodule CellToolbar
17 * @submodule CellToolbar
18 */
18 */
19 var IPython = (function (IPython) {
19 var IPython = (function (IPython) {
20 "use strict";
20 "use strict";
21
21
22
22
23 /**
23 /**
24 * @constructor
24 * @constructor
25 * @class CellToolbar
25 * @class CellToolbar
26 * @param {The cell to attach the metadata UI to} cell
26 * @param {The cell to attach the metadata UI to} cell
27 */
27 */
28 var CellToolbar = function (cell) {
28 var CellToolbar = function (cell) {
29 CellToolbar._instances.push(this);
29 CellToolbar._instances.push(this);
30 this.inner_element = $('<div/>');
30 this.inner_element = $('<div/>');
31 this.cell = cell;
31 this.cell = cell;
32 this.element = $('<div/>').addClass('celltoolbar')
32 this.element = $('<div/>').addClass('celltoolbar')
33 .append(this.inner_element)
33 .append(this.inner_element)
34 this.rebuild();
34 this.rebuild();
35 return this;
35 return this;
36 };
36 };
37
37
38 CellToolbar.dropdown_preset_element = $('<select/>')
38 CellToolbar.dropdown_preset_element = $('<select/>')
39 .addClass('ui-widget ui-widget-content')
39 .addClass('ui-widget ui-widget-content')
40 .attr('id','celltoolbar_selector')
40 .attr('id', 'celltoolbar_selector')
41 .append($('<option/>').attr('value','').text('-'))
41 .append($('<option/>').attr('value', '').text('-'))
42
42
43 CellToolbar.dropdown_preset_element.change(function(){
43 CellToolbar.dropdown_preset_element.change(function(){
44 var val = CellToolbar.dropdown_preset_element.val()
44 var val = CellToolbar.dropdown_preset_element.val()
45 if(val ==''){
45 if(val ==''){
46 $('body').removeClass('celltoolbar-on')
46 $('body').removeClass('celltoolbar-on')
47 } else {
47 } else {
48 $('body').addClass('celltoolbar-on')
48 $('body').addClass('celltoolbar-on')
49 CellToolbar.set_preset(val)
49 CellToolbar.set_preset(val)
50 }
50 }
51 })
51 })
52
52
53
53
54
54
55 /**
55 /**
56 * Class variable that should contain a dict of all availlable callback
56 * Class variable that should contain a dict of all availlable callback
57 * we need to think of wether or not we allow nested namespace
57 * we need to think of wether or not we allow nested namespace
58 * @property _callback_dict
58 * @property _callback_dict
59 * @private
59 * @private
60 */
60 */
61 CellToolbar._callback_dict = {};
61 CellToolbar._callback_dict = {};
62
62
63 /**
63 /**
64 * Class variable that should contain the reverse order list of the button
64 * Class variable that should contain the reverse order list of the button
65 * to add to the toolbar of each cell
65 * to add to the toolbar of each cell
66 * @property _ui_controls_list
66 * @property _ui_controls_list
67 * @private
67 * @private
68 */
68 */
69 CellToolbar._ui_controls_list = [];
69 CellToolbar._ui_controls_list = [];
70
70
71 /**
71 /**
72 * keep a list of all instances to
72 * keep a list of all instances to
73 * be able to llop over them...
73 * be able to llop over them...
74 * but how to 'destroy' them ?
74 * but how to 'destroy' them ?
75 * have to think about it...
75 * have to think about it...
76 * or loop over the cells, and find their CellToolbar instances.
76 * or loop over the cells, and find their CellToolbar instances.
77 * @private
77 * @private
78 * @property _instances
78 * @property _instances
79 */
79 */
80 CellToolbar._instances =[]
80 CellToolbar._instances =[]
81
81
82 /**
82 /**
83 * keep a list of all the availlabel presets for the toolbar
83 * keep a list of all the availlabel presets for the toolbar
84 * @private
84 * @private
85 * @property _presets
85 * @property _presets
86 */
86 */
87 CellToolbar._presets ={}
87 CellToolbar._presets ={}
88
88
89 // this is by design not a prototype.
89 // this is by design not a prototype.
90 /**
90 /**
91 * Register a callback to create an UI element in a cell toolbar.
91 * Register a callback to create an UI element in a cell toolbar.
92 * @method register_callback
92 * @method register_callback
93 * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
93 * @param name {String} name to use to refer to the callback. It is advised to use a prefix with the name
94 * for easier sorting and avoid collision
94 * for easier sorting and avoid collision
95 * @param callback {function(div, cell)} callback that will be called to generate the ui element
95 * @param callback {function(div, cell)} callback that will be called to generate the ui element
96 *
96 *
97 *
97 *
98 * The callback will receive the following element :
98 * The callback will receive the following element :
99 *
99 *
100 * * a div in which to add element.
100 * * a div in which to add element.
101 * * the cell it is responsable from
101 * * the cell it is responsable from
102 *
102 *
103 * @example
103 * @example
104 *
104 *
105 * Example that create callback for a button that toggle between `true` and `false` label,
105 * Example that create callback for a button that toggle between `true` and `false` label,
106 * with the metadata under the key 'foo' to reflect the status of the button.
106 * with the metadata under the key 'foo' to reflect the status of the button.
107 *
107 *
108 * // first param reference to a DOM div
108 * // first param reference to a DOM div
109 * // second param reference to the cell.
109 * // second param reference to the cell.
110 * var toggle = function(div, cell) {
110 * var toggle = function(div, cell) {
111 * var button_container = $(div)
111 * var button_container = $(div)
112 *
112 *
113 * // let's create a button that show the current value of the metadata
113 * // let's create a button that show the current value of the metadata
114 * var button = $('<div/>').button({label:String(cell.metadata.foo)});
114 * var button = $('<div/>').button({label:String(cell.metadata.foo)});
115 *
115 *
116 * // On click, change the metadata value and update the button label
116 * // On click, change the metadata value and update the button label
117 * button.click(function(){
117 * button.click(function(){
118 * var v = cell.metadata.foo;
118 * var v = cell.metadata.foo;
119 * cell.metadata.foo = !v;
119 * cell.metadata.foo = !v;
120 * button.button("option","label",String(!v));
120 * button.button("option", "label", String(!v));
121 * })
121 * })
122 *
122 *
123 * // add the button to the DOM div.
123 * // add the button to the DOM div.
124 * button_container.append(button);
124 * button_container.append(button);
125 * }
125 * }
126 *
126 *
127 * // now we register the callback under the name `foo` to give the
127 * // now we register the callback under the name `foo` to give the
128 * // user the ability to use it later
128 * // user the ability to use it later
129 * CellToolbar.register_callback('foo',toggle);
129 * CellToolbar.register_callback('foo', toggle);
130 */
130 */
131 CellToolbar.register_callback = function(name, callback){
131 CellToolbar.register_callback = function(name, callback){
132 // what do we do if name already exist ?
132 // what do we do if name already exist ?
133 CellToolbar._callback_dict[name] = callback;
133 CellToolbar._callback_dict[name] = callback;
134 };
134 };
135
135
136 /**
136 /**
137 * Register a preset of UI element in a cell toolbar.
137 * Register a preset of UI element in a cell toolbar.
138 * Not supported Yet.
138 * Not supported Yet.
139 * @method register_preset
139 * @method register_preset
140 * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
140 * @param name {String} name to use to refer to the preset. It is advised to use a prefix with the name
141 * for easier sorting and avoid collision
141 * for easier sorting and avoid collision
142 * @param preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
142 * @param preset_list {List of String} reverse order of the button in the toolbar. Each String of the list
143 * should correspond to a name of a registerd callback.
143 * should correspond to a name of a registerd callback.
144 *
144 *
145 * @private
145 * @private
146 * @example
146 * @example
147 *
147 *
148 * CellToolbar.register_callback('foo.c1',function(div,cell){...});
148 * CellToolbar.register_callback('foo.c1', function(div, cell){...});
149 * CellToolbar.register_callback('foo.c2',function(div,cell){...});
149 * CellToolbar.register_callback('foo.c2', function(div, cell){...});
150 * CellToolbar.register_callback('foo.c3',function(div,cell){...});
150 * CellToolbar.register_callback('foo.c3', function(div, cell){...});
151 * CellToolbar.register_callback('foo.c4',function(div,cell){...});
151 * CellToolbar.register_callback('foo.c4', function(div, cell){...});
152 * CellToolbar.register_callback('foo.c5',function(div,cell){...});
152 * CellToolbar.register_callback('foo.c5', function(div, cell){...});
153 *
153 *
154 * CellToolbar.register_preset('foo.foo_preset1',['foo.c1','foo.c2','foo.c5'])
154 * CellToolbar.register_preset('foo.foo_preset1', ['foo.c1', 'foo.c2', 'foo.c5'])
155 * CellToolbar.register_preset('foo.foo_preset2',['foo.c4','foo.c5'])
155 * CellToolbar.register_preset('foo.foo_preset2', ['foo.c4', 'foo.c5'])
156 */
156 */
157 CellToolbar.register_preset = function(name, preset_list){
157 CellToolbar.register_preset = function(name, preset_list){
158 CellToolbar._presets[name] = preset_list
158 CellToolbar._presets[name] = preset_list
159 CellToolbar.dropdown_preset_element.append(
159 CellToolbar.dropdown_preset_element.append(
160 $('<option/>').attr('value',name).text(name)
160 $('<option/>').attr('value', name).text(name)
161 )
161 )
162 }
162 }
163 /**
163 /**
164 * set an UI preset from `register_preset`
164 * set an UI preset from `register_preset`
165 * @method set_preset
165 * @method set_preset
166 * @param preset_name {String} string corresponding to the preset name
166 * @param preset_name {String} string corresponding to the preset name
167 *
167 *
168 * @static
168 * @static
169 * @private
169 * @private
170 * @example
170 * @example
171 *
171 *
172 * CellToolbar.set_preset('foo.foo_preset1');
172 * CellToolbar.set_preset('foo.foo_preset1');
173 */
173 */
174 CellToolbar.set_preset= function(preset_name){
174 CellToolbar.set_preset= function(preset_name){
175 var preset = CellToolbar._presets[preset_name];
175 var preset = CellToolbar._presets[preset_name];
176
176
177 if(preset != undefined){
177 if(preset != undefined){
178 CellToolbar._ui_controls_list = preset;
178 CellToolbar._ui_controls_list = preset;
179 CellToolbar.rebuild_all();
179 CellToolbar.rebuild_all();
180 }
180 }
181 }
181 }
182
182
183
183
184 // this is by design not a prototype.
184 // this is by design not a prototype.
185 /**
185 /**
186 * This should be called on the class and not on a instance as it will trigger
186 * This should be called on the class and not on a instance as it will trigger
187 * rebuild of all the instances.
187 * rebuild of all the instances.
188 * @method rebuild_all
188 * @method rebuild_all
189 * @static
189 * @static
190 *
190 *
191 */
191 */
192 CellToolbar.rebuild_all = function(){
192 CellToolbar.rebuild_all = function(){
193 for(var i in CellToolbar._instances){
193 for(var i in CellToolbar._instances){
194 CellToolbar._instances[i].rebuild();
194 CellToolbar._instances[i].rebuild();
195 }
195 }
196 }
196 }
197
197
198 /**
198 /**
199 * Rebuild all the button on the toolbar to update it's state.
199 * Rebuild all the button on the toolbar to update it's state.
200 * @method rebuild
200 * @method rebuild
201 */
201 */
202 CellToolbar.prototype.rebuild = function(){
202 CellToolbar.prototype.rebuild = function(){
203 // strip evrything from the div
203 // strip evrything from the div
204 // which is probabli metainner.
204 // which is probabli metainner.
205 // or this.element.
205 // or this.element.
206 this.inner_element.empty();
206 this.inner_element.empty();
207
207
208 var cdict = CellToolbar._callback_dict;
208 var cdict = CellToolbar._callback_dict;
209 var preset = CellToolbar._ui_controls_list;
209 var preset = CellToolbar._ui_controls_list;
210 // Yes we iterate on the class varaible, not the instance one.
210 // Yes we iterate on the class varaible, not the instance one.
211 for ( var index in CellToolbar._ui_controls_list){
211 for ( var index in CellToolbar._ui_controls_list){
212 var local_div = $('<div/>').addClass('button_container');
212 var local_div = $('<div/>').addClass('button_container');
213 // Note,
213 // Note,
214 // do this the other way, wrap in try/catch and don't append if any errors.
214 // do this the other way, wrap in try/catch and don't append if any errors.
215 this.inner_element.append(local_div)
215 this.inner_element.append(local_div)
216 cdict[preset[index]](local_div,this.cell)
216 cdict[preset[index]](local_div, this.cell)
217 }
217 }
218
218
219 }
219 }
220
220
221
222
223
224
221
225 /**
222 /**
226 */
223 */
227 CellToolbar.utils = {};
224 CellToolbar.utils = {};
228
225
229 /**
226 /**
230 * A utility function to generate bindings between a checkbox and metadata
227 * A utility function to generate bindings between a checkbox and cell/metadata
231 * @method utils.checkbox_ui_generator
228 * @method utils.checkbox_ui_generator
232 * @static
229 * @static
233 *
230 *
234 * @param name {string} Label in front of the checkbox
231 * @param name {string} Label in front of the checkbox
235 * @param setter {function( metadata_dict, newValue )}
232 * @param setter {function( cell, newValue )}
236 * A setter method to set the newValue of the metadata dictionnary
233 * A setter method to set the newValue
237 * @param getter {function( metadata )}
234 * @param getter {function( cell )}
238 * A getter methods which return the current value of the metadata.
235 * A getter methods which return the current value.
239 *
236 *
240 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
237 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
241 *
238 *
242 * @example
239 * @example
243 *
240 *
244 * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
241 * An exmple that bind the subkey `slideshow.isSectionStart` to a checkbox with a `New Slide` label
245 *
242 *
246 * var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
243 * var newSlide = CellToolbar.utils.checkbox_ui_generator('New Slide',
247 * // setter
244 * // setter
248 * function(metadata,value){
245 * function(cell, value){
249 * // we check that the slideshow namespace exist and create it if needed
246 * // we check that the slideshow namespace exist and create it if needed
250 * if (metadata.slideshow == undefined){metadata.slideshow = {}}
247 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
251 * // set the value
248 * // set the value
252 * metadata.slideshow.isSectionStart = value
249 * cell.metadata.slideshow.isSectionStart = value
253 * },
250 * },
254 * //geter
251 * //geter
255 * function(metadata){ var ns = metadata.slideshow;
252 * function(cell){ var ns = cell.metadata.slideshow;
256 * // if the slideshow namespace does not exist return `undefined`
253 * // if the slideshow namespace does not exist return `undefined`
257 * // (will be interpreted as `false` by checkbox) otherwise
254 * // (will be interpreted as `false` by checkbox) otherwise
258 * // return the value
255 * // return the value
259 * return (ns == undefined)? undefined: ns.isSectionStart
256 * return (ns == undefined)? undefined: ns.isSectionStart
260 * }
257 * }
261 * );
258 * );
262 *
259 *
263 * CellToolbar.register_callback('newSlide', newSlide);
260 * CellToolbar.register_callback('newSlide', newSlide);
264 *
261 *
265 */
262 */
266 CellToolbar.utils.checkbox_ui_generator = function(name,setter,getter){
263 CellToolbar.utils.checkbox_ui_generator = function(name, setter, getter){
267 return function(div, cell) {
264 return function(div, cell) {
268 var button_container = $(div)
265 var button_container = $(div)
269
266
270 var chkb = $('<input/>').attr('type','checkbox');
267 var chkb = $('<input/>').attr('type', 'checkbox');
271 var lbl = $('<label/>').append($('<span/>').text(name).css('font-size','77%'));
268 var lbl = $('<label/>').append($('<span/>').text(name).css('font-size', '77%'));
272 lbl.append(chkb);
269 lbl.append(chkb);
273 chkb.attr("checked",getter(cell.metadata));
270 chkb.attr("checked", getter(cell));
274
271
275 chkb.click(function(){
272 chkb.click(function(){
276 var v = getter(cell.metadata);
273 var v = getter(cell);
277 setter(cell.metadata,!v);
274 setter(cell, !v);
278 chkb.attr("checked",!v);
275 chkb.attr("checked", !v);
279 })
276 })
280 button_container.append($('<div/>').append(lbl));
277 button_container.append($('<div/>').append(lbl));
281
278
282 }
279 }
283 }
280 }
284
281
285 /**
282 /**
286 * A utility function to generate bindings between a dropdown list and metadata
283 * A utility function to generate bindings between a dropdown list cell
287 * @method utils.select_ui_generator
284 * @method utils.select_ui_generator
288 * @static
285 * @static
289 *
286 *
290 * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
287 * @param list_list {list of sublist} List of sublist of metadata value and name in the dropdown list.
291 * subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
288 * subslit shoud contain 2 element each, first a string that woul be displayed in the dropdown list,
292 * and second the corresponding value for the metadata to be passed to setter/return by getter.
289 * and second the corresponding value to be passed to setter/return by getter.
293 * @param setter {function( metadata_dict, newValue )}
290 * @param setter {function( cell, newValue )}
294 * A setter method to set the newValue of the metadata dictionnary
291 * A setter method to set the newValue
295 * @param getter {function( metadata )}
292 * @param getter {function( cell )}
296 * A getter methods which return the current value of the metadata.
293 * A getter methods which return the current value of the metadata.
297 * @param [label=""] {String} optionnal label for the dropdown menu
294 * @param [label=""] {String} optionnal label for the dropdown menu
298 *
295 *
299 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
296 * @return callback {function( div, cell )} Callback to be passed to `register_callback`
300 *
297 *
301 * @example
298 * @example
302 *
299 *
303 * var select_type = CellToolbar.utils.select_ui_generator([
300 * var select_type = CellToolbar.utils.select_ui_generator([
304 * ["-" ,undefined ],
301 * ["-" , undefined ],
305 * ["Header Slide" ,"header_slide" ],
302 * ["Header Slide" , "header_slide" ],
306 * ["Slide" ,"slide" ],
303 * ["Slide" , "slide" ],
307 * ["Fragment" ,"fragment" ],
304 * ["Fragment" , "fragment" ],
308 * ["Skip" ,"skip" ],
305 * ["Skip" , "skip" ],
309 * ],
306 * ],
310 * // setter
307 * // setter
311 * function(metadata,value){
308 * function(cell, value){
312 * // we check that the slideshow namespace exist and create it if needed
309 * // we check that the slideshow namespace exist and create it if needed
313 * if (metadata.slideshow == undefined){metadata.slideshow = {}}
310 * if (cell.metadata.slideshow == undefined){cell.metadata.slideshow = {}}
314 * // set the value
311 * // set the value
315 * metadata.slideshow.slide_type = value
312 * cell.metadata.slideshow.slide_type = value
316 * },
313 * },
317 * //geter
314 * //geter
318 * function(metadata){ var ns = metadata.slideshow;
315 * function(cell){ var ns = cell.metadata.slideshow;
319 * // if the slideshow namespace does not exist return `undefined`
316 * // if the slideshow namespace does not exist return `undefined`
320 * // (will be interpreted as `false` by checkbox) otherwise
317 * // (will be interpreted as `false` by checkbox) otherwise
321 * // return the value
318 * // return the value
322 * return (ns == undefined)? undefined: ns.slide_type
319 * return (ns == undefined)? undefined: ns.slide_type
323 * }
320 * }
324 * CellToolbar.register_callback('slideshow.select',select_type);
321 * CellToolbar.register_callback('slideshow.select', select_type);
325 *
322 *
326 */
323 */
327 CellToolbar.utils.select_ui_generator = function(list_list,setter, getter, label){
324 CellToolbar.utils.select_ui_generator = function(list_list, setter, getter, label){
328 label= label? label: "";
325 label= label? label: "";
329 return function(div, cell) {
326 return function(div, cell) {
330 var button_container = $(div)
327 var button_container = $(div)
331 var lbl = $("<label/>").append($('<span/>').text(label).css('font-size','77%'));
328 var lbl = $("<label/>").append($('<span/>').text(label).css('font-size', '77%'));
332 var select = $('<select/>');
329 var select = $('<select/>');
333 for(var itemn in list_list){
330 for(var itemn in list_list){
334 var opt = $('<option/>');
331 var opt = $('<option/>');
335 opt.attr('value',list_list[itemn][1])
332 opt.attr('value', list_list[itemn][1])
336 opt.text(list_list[itemn][0])
333 opt.text(list_list[itemn][0])
337 select.append(opt);
334 select.append(opt);
338 }
335 }
339 select.val(getter(cell.metadata));
336 select.val(getter(cell));
340
341 select.change(function(){
337 select.change(function(){
342 setter(cell.metadata,select.val());
338 setter(cell, select.val());
343 });
339 });
344 button_container.append($('<div/>').append(lbl).append(select));
340 button_container.append($('<div/>').append(lbl).append(select));
345
341
346 }
342 }
347 };
343 };
348
344
349
345
350 IPython.CellToolbar = CellToolbar;
346 IPython.CellToolbar = CellToolbar;
351
347
352 return IPython;
348 return IPython;
353 }(IPython));
349 }(IPython));
@@ -1,217 +1,224 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2012 The IPython Development Team
2 // Copyright (C) 2012 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // CellToolbar Example
9 // CellToolbar Example
10 //============================================================================
10 //============================================================================
11
11
12 /**
12 /**
13 * Example Use for the CellToolbar library
13 * Example Use for the CellToolbar library
14 * add the following to your custom.js to load
14 * add the following to your custom.js to load
15 * Celltoolbar UI for slideshow
15 * Celltoolbar UI for slideshow
16 *
16 *
17 * ```
17 * ```
18 * $.getScript('/static/js/examples/celltoolbar.example.js');
18 * $.getScript('/static/js/examples/celltoolbar.example.js');
19 * ```
19 * ```
20 */
20 */
21 // IIFE without asignement, we don't modifiy the IPython namespace
21 // IIFE without asignement, we don't modifiy the IPython namespace
22 (function (IPython) {
22 (function (IPython) {
23 "use strict";
23 "use strict";
24
24
25 var CellToolbar = IPython.CellToolbar;
25 var CellToolbar = IPython.CellToolbar;
26
26
27
27
28 var raw_edit = function(cell){
28 var raw_edit = function(cell){
29
29
30 var md = cell.metadata
30 var md = cell.metadata
31 var error_div = $('<div/>').css('color','red')
31 var error_div = $('<div/>').css('color','red')
32
32
33 var textarea = $('<textarea/>')
33 var textarea = $('<textarea/>')
34 .attr('rows','13')
34 .attr('rows','13')
35 .attr('cols','75')
35 .attr('cols','75')
36 .attr('name','metadata')
36 .attr('name','metadata')
37 .text(JSON.stringify(md, null,4)||'');
37 .text(JSON.stringify(md, null,4)||'');
38 var dialogform = $('<div/>').attr('title','Edit the metadata')
38 var dialogform = $('<div/>').attr('title','Edit the metadata')
39 .append(
39 .append(
40 $('<form/>').append(
40 $('<form/>').append(
41 $('<fieldset/>').append(
41 $('<fieldset/>').append(
42 $('<label/>')
42 $('<label/>')
43 .attr('for','metadata')
43 .attr('for','metadata')
44 .text("Metadata (I know what I'm dooing and I won't complain if it breaks my notebook)")
44 .text("Metadata (I know what I'm dooing and I won't complain if it breaks my notebook)")
45 )
45 )
46 .append(error_div)
46 .append(error_div)
47 .append($('<br/>'))
47 .append($('<br/>'))
48 .append(
48 .append(
49 textarea
49 textarea
50 )
50 )
51 )
51 )
52 );
52 );
53 var editor = CodeMirror.fromTextArea(textarea[0], {
53 var editor = CodeMirror.fromTextArea(textarea[0], {
54 lineNumbers: true,
54 lineNumbers: true,
55 matchBrackets: true,
55 matchBrackets: true,
56 });
56 });
57 $(dialogform).dialog({
57 $(dialogform).dialog({
58 autoOpen: true,
58 autoOpen: true,
59 height: 300,
59 height: 300,
60 width: 650,
60 width: 650,
61 modal: true,
61 modal: true,
62 buttons: {
62 buttons: {
63 "Ok": function() {
63 "Ok": function() {
64 //validate json and set it
64 //validate json and set it
65 try {
65 try {
66 var json = JSON.parse(editor.getValue());
66 var json = JSON.parse(editor.getValue());
67 cell.metadata = json;
67 cell.metadata = json;
68 $( this ).dialog( "close" );
68 $( this ).dialog( "close" );
69 }
69 }
70 catch(e)
70 catch(e)
71 {
71 {
72 error_div.text('Warning, invalid json, not saved');
72 error_div.text('Warning, invalid json, not saved');
73 }
73 }
74 },
74 },
75 Cancel: function() {
75 Cancel: function() {
76 $( this ).dialog( "close" );
76 $( this ).dialog( "close" );
77 }
77 }
78 },
78 },
79 close: function() {
79 close: function() {
80 //cleanup on close
80 //cleanup on close
81 $(this).remove();
81 $(this).remove();
82 }
82 }
83 });
83 });
84 editor.refresh();
84 editor.refresh();
85 }
85 }
86
86
87 var add_raw_edit_button = function(div, cell) {
87 var add_raw_edit_button = function(div, cell) {
88 var button_container = div
88 var button_container = div
89 var button = $('<div/>').button({label:'Raw Edit'})
89 var button = $('<div/>').button({label:'Raw Edit'})
90 .click(function(){raw_edit(cell); return false;})
90 .click(function(){raw_edit(cell); return false;})
91 button_container.append(button);
91 button_container.append(button);
92 }
92 }
93
93
94 CellToolbar.register_callback('example.rawedit',add_raw_edit_button);
94 CellToolbar.register_callback('example.rawedit',add_raw_edit_button);
95 var example_preset = []
95 var example_preset = []
96 example_preset.push('example.rawedit');
96 example_preset.push('example.rawedit');
97
97
98
98
99 var simple_button = function(div, cell) {
99 var simple_button = function(div, cell) {
100 var button_container = $(div);
100 var button_container = $(div);
101 var button = $('<div/>').button({icons:{primary:'ui-icon-locked'}});
101 var button = $('<div/>').button({icons:{primary:'ui-icon-locked'}});
102 var fun = function(value){
102 var fun = function(value){
103 try{
103 try{
104 if(value){
104 if(value){
105 cell.code_mirror.setOption('readOnly','nocursor')
105 cell.code_mirror.setOption('readOnly','nocursor')
106 button.button('option','icons',{primary:'ui-icon-locked'})
106 button.button('option','icons',{primary:'ui-icon-locked'})
107 } else {
107 } else {
108 cell.code_mirror.setOption('readOnly','false')
108 cell.code_mirror.setOption('readOnly','false')
109 button.button('option','icons',{primary:'ui-icon-unlocked'})
109 button.button('option','icons',{primary:'ui-icon-unlocked'})
110 }
110 }
111 } catch(e){}
111 } catch(e){}
112
112
113 }
113 }
114 fun(cell.metadata.ro)
114 fun(cell.metadata.ro)
115 button.click(function(){
115 button.click(function(){
116 var v = cell.metadata.ro;
116 var v = cell.metadata.ro;
117 var locked = !v;
117 var locked = !v;
118 cell.metadata.ro = locked;
118 cell.metadata.ro = locked;
119 fun(locked)
119 fun(locked)
120 })
120 })
121 .css('height','16px')
121 .css('height','16px')
122 .css('width','35px');
122 .css('width','35px');
123 button_container.append(button);
123 button_container.append(button);
124 }
124 }
125
125
126 CellToolbar.register_callback('example.lock',simple_button);
126 CellToolbar.register_callback('example.lock',simple_button);
127 example_preset.push('example.lock');
127 example_preset.push('example.lock');
128
128
129 var toggle_test = function(div, cell) {
129 var toggle_test = function(div, cell) {
130 var button_container = $(div)
130 var button_container = $(div)
131 var button = $('<div/>')
131 var button = $('<div/>')
132 .button({label:String(cell.metadata.foo)}).
132 .button({label:String(cell.metadata.foo)}).
133 css('width','65px');
133 css('width','65px');
134 button.click(function(){
134 button.click(function(){
135 var v = cell.metadata.foo;
135 var v = cell.metadata.foo;
136 cell.metadata.foo = !v;
136 cell.metadata.foo = !v;
137 button.button("option","label",String(!v));
137 button.button("option","label",String(!v));
138 })
138 })
139 button_container.append(button);
139 button_container.append(button);
140 }
140 }
141
141
142 CellToolbar.register_callback('example.toggle',toggle_test);
142 CellToolbar.register_callback('example.toggle',toggle_test);
143 example_preset.push('example.toggle');
143 example_preset.push('example.toggle');
144
144
145 var checkbox_test = function(div, cell) {
145 var checkbox_test = CellToolbar.utils.checkbox_ui_generator('Yes/No',
146 var button_container = $(div)
146 // setter
147 function(cell, value){
148 // we check that the slideshow namespace exist and create it if needed
149 if (cell.metadata.yn_test == undefined){cell.metadata.yn_test = {}}
150 // set the value
151 cell.metadata.yn_test.value = value
152 },
153 //geter
154 function(cell){ var ns = cell.metadata.yn_test;
155 // if the slideshow namespace does not exist return `undefined`
156 // (will be interpreted as `false` by checkbox) otherwise
157 // return the value
158 return (ns == undefined)? undefined: ns.value
159 }
160 );
147
161
148 var chkb = $('<input/>').attr('type','checkbox');
149 var lbl = $('<label/>').append($('<span/>').text('bar :').css('font-size','77%'));
150 lbl.append(chkb);
151 chkb.attr("checked",cell.metadata.bar);
152 chkb.click(function(){
153 var v = cell.metadata.bar;
154 cell.metadata.bar = !v;
155 chkb.attr("checked",!v);
156 })
157 button_container.append($('<div/>').append(lbl));
158
159 }
160
162
161 CellToolbar.register_callback('example.checkbox',checkbox_test);
163 CellToolbar.register_callback('example.checkbox',checkbox_test);
162 example_preset.push('example.checkbox');
164 example_preset.push('example.checkbox');
163
165
164 var select_test = function(div, cell) {
166 var select_test = CellToolbar.utils.select_ui_generator([
165 var button_container = $(div)
167 ["-" ,undefined ],
166
168 ["Header Slide" ,"header_slide" ],
167 var select = $('<select/>');
169 ["Slide" ,"slide" ],
168
170 ["Fragment" ,"fragment" ],
169 select.append($('<option/>').attr('value','foo').text('foo'));
171 ["Skip" ,"skip" ],
170 select.append($('<option/>').attr('value','bar').text('bar'));
172 ],
171 select.append($('<option/>').attr('value','qux').text('qux'));
173 // setter
172 select.append($('<option/>').attr('value','zip').text('zip'));
174 function(cell,value){
173 select.val(cell.metadata.option);
175 // we check that the slideshow namespace exist and create it if needed
174 select.change(function(){
176 if (cell.metadata.test == undefined){cell.metadata.test = {}}
175 cell.metadata.option = select.val();
177 // set the value
178 cell.metadata.test.slide_type = value
179 },
180 //geter
181 function(cell){ var ns = cell.metadata.test;
182 // if the slideshow namespace does not exist return `undefined`
183 // (will be interpreted as `false` by checkbox) otherwise
184 // return the value
185 return (ns == undefined)? undefined: ns.slide_type
176 });
186 });
177 button_container.append($('<div/>').append(select));
178
179 }
180
187
181 CellToolbar.register_callback('example.select',select_test);
188 CellToolbar.register_callback('example.select',select_test);
182 example_preset.push('example.select');
189 example_preset.push('example.select');
183
190
184 var simple_dialog = function(title,text){
191 var simple_dialog = function(title,text){
185 var dlg = $('<div/>').attr('title',title)
192 var dlg = $('<div/>').attr('title',title)
186 .append($('<p/>').text(text))
193 .append($('<p/>').text(text))
187 $(dlg).dialog({
194 $(dlg).dialog({
188 autoOpen: true,
195 autoOpen: true,
189 height: 300,
196 height: 300,
190 width: 650,
197 width: 650,
191 modal: true,
198 modal: true,
192 close: function() {
199 close: function() {
193 //cleanup on close
200 //cleanup on close
194 $(this).remove();
201 $(this).remove();
195 }
202 }
196 });
203 });
197 }
204 }
198
205
199 var add_simple_dialog_button = function(div, cell) {
206 var add_simple_dialog_button = function(div, cell) {
200 var help_text = ["This is the Metadata editting UI.",
207 var help_text = ["This is the Metadata editting UI.",
201 "It heavily rely on plugin to work ",
208 "It heavily rely on plugin to work ",
202 "and is still under developpement. You shouldn't wait too long before",
209 "and is still under developpement. You shouldn't wait too long before",
203 " seeing some customisable buttons in those toolbar."
210 " seeing some customisable buttons in those toolbar."
204 ].join('\n')
211 ].join('\n')
205 var button_container = $(div)
212 var button_container = $(div)
206 var button = $('<div/>').button({label:'?'})
213 var button = $('<div/>').button({label:'?'})
207 .click(function(){simple_dialog('help',help_text); return false;})
214 .click(function(){simple_dialog('help',help_text); return false;})
208 button_container.append(button);
215 button_container.append(button);
209 }
216 }
210
217
211 CellToolbar.register_callback('example.help',add_simple_dialog_button)
218 CellToolbar.register_callback('example.help',add_simple_dialog_button)
212 example_preset.push('example.help')
219 example_preset.push('example.help')
213
220
214 CellToolbar.register_preset('example',example_preset);
221 CellToolbar.register_preset('example',example_preset);
215 console.log('Example extension for metadata editting loaded.');
222 console.log('Example extension for metadata editting loaded.');
216
223
217 }(IPython));
224 }(IPython));
General Comments 0
You need to be logged in to leave comments. Login now