Show More
@@ -1,158 +1,159 b'' | |||||
1 | // Copyright (c) IPython Development Team. |
|
1 | // Copyright (c) IPython Development Team. | |
2 | // Distributed under the terms of the Modified BSD License. |
|
2 | // Distributed under the terms of the Modified BSD License. | |
3 |
|
3 | |||
4 | define([ |
|
4 | define([ | |
5 | "widgets/js/widget", |
|
5 | "widgets/js/widget", | |
6 | "jquery", |
|
6 | "jquery", | |
7 | "bootstrap", |
|
7 | "bootstrap", | |
8 | ], function(widget, $){ |
|
8 | ], function(widget, $){ | |
9 |
|
9 | |||
10 | var CheckboxView = widget.DOMWidgetView.extend({ |
|
10 | var CheckboxView = widget.DOMWidgetView.extend({ | |
11 | render : function(){ |
|
11 | render : function(){ | |
12 | /** |
|
12 | /** | |
13 | * Called when view is rendered. |
|
13 | * Called when view is rendered. | |
14 | */ |
|
14 | */ | |
15 | this.$el |
|
15 | this.$el | |
16 | .addClass('widget-hbox widget-checkbox'); |
|
16 | .addClass('widget-hbox widget-checkbox'); | |
17 | this.$label = $('<div />') |
|
17 | this.$label = $('<div />') | |
18 | .addClass('widget-label') |
|
18 | .addClass('widget-label') | |
19 | .appendTo(this.$el) |
|
19 | .appendTo(this.$el) | |
20 | .hide(); |
|
20 | .hide(); | |
21 | this.$checkbox = $('<input />') |
|
21 | this.$checkbox = $('<input />') | |
22 | .attr('type', 'checkbox') |
|
22 | .attr('type', 'checkbox') | |
23 | .appendTo(this.$el) |
|
23 | .appendTo(this.$el) | |
24 | .click($.proxy(this.handle_click, this)); |
|
24 | .click($.proxy(this.handle_click, this)); | |
25 |
|
25 | |||
26 | this.update(); // Set defaults. |
|
26 | this.update(); // Set defaults. | |
27 | }, |
|
27 | }, | |
28 |
|
28 | |||
29 | update_attr: function(name, value) { |
|
29 | update_attr: function(name, value) { | |
30 | /** |
|
30 | /** | |
31 | * Set a css attr of the widget view. |
|
31 | * Set a css attr of the widget view. | |
32 | */ |
|
32 | */ | |
33 | if (name == 'padding' || name == 'margin') { |
|
33 | if (name == 'padding' || name == 'margin') { | |
34 | this.$el.css(name, value); |
|
34 | this.$el.css(name, value); | |
35 | } else { |
|
35 | } else { | |
36 | this.$checkbox.css(name, value); |
|
36 | this.$checkbox.css(name, value); | |
37 | } |
|
37 | } | |
38 | }, |
|
38 | }, | |
39 |
|
39 | |||
40 | handle_click: function() { |
|
40 | handle_click: function() { | |
41 | /** |
|
41 | /** | |
42 | * Handles when the checkbox is clicked. |
|
42 | * Handles when the checkbox is clicked. | |
43 | * |
|
43 | * | |
44 | * Calling model.set will trigger all of the other views of the |
|
44 | * Calling model.set will trigger all of the other views of the | |
45 | * model to update. |
|
45 | * model to update. | |
46 | */ |
|
46 | */ | |
47 | var value = this.model.get('value'); |
|
47 | var value = this.model.get('value'); | |
48 | this.model.set('value', ! value, {updated_view: this}); |
|
48 | this.model.set('value', ! value, {updated_view: this}); | |
49 | this.touch(); |
|
49 | this.touch(); | |
50 | }, |
|
50 | }, | |
51 |
|
51 | |||
52 | update : function(options){ |
|
52 | update : function(options){ | |
53 | /** |
|
53 | /** | |
54 | * Update the contents of this view |
|
54 | * Update the contents of this view | |
55 | * |
|
55 | * | |
56 | * Called when the model is changed. The model may have been |
|
56 | * Called when the model is changed. The model may have been | |
57 | * changed by another view or by a state update from the back-end. |
|
57 | * changed by another view or by a state update from the back-end. | |
58 | */ |
|
58 | */ | |
59 | this.$checkbox.prop('checked', this.model.get('value')); |
|
59 | this.$checkbox.prop('checked', this.model.get('value')); | |
60 |
|
60 | |||
61 | if (options === undefined || options.updated_view != this) { |
|
61 | if (options === undefined || options.updated_view != this) { | |
62 | var disabled = this.model.get('disabled'); |
|
62 | var disabled = this.model.get('disabled'); | |
63 | this.$checkbox.prop('disabled', disabled); |
|
63 | this.$checkbox.prop('disabled', disabled); | |
64 |
|
64 | |||
65 | var description = this.model.get('description'); |
|
65 | var description = this.model.get('description'); | |
66 | if (description.trim().length === 0) { |
|
66 | if (description.trim().length === 0) { | |
67 | this.$label.hide(); |
|
67 | this.$label.hide(); | |
68 | } else { |
|
68 | } else { | |
69 | this.typeset(this.$label, description); |
|
69 | this.typeset(this.$label, description); | |
70 | this.$label.show(); |
|
70 | this.$label.show(); | |
71 | } |
|
71 | } | |
72 | } |
|
72 | } | |
73 | return CheckboxView.__super__.update.apply(this); |
|
73 | return CheckboxView.__super__.update.apply(this); | |
74 | }, |
|
74 | }, | |
75 |
|
75 | |||
76 | }); |
|
76 | }); | |
77 |
|
77 | |||
78 |
|
78 | |||
79 | var ToggleButtonView = widget.DOMWidgetView.extend({ |
|
79 | var ToggleButtonView = widget.DOMWidgetView.extend({ | |
80 | render : function() { |
|
80 | render : function() { | |
81 | /** |
|
81 | /** | |
82 | * Called when view is rendered. |
|
82 | * Called when view is rendered. | |
83 | */ |
|
83 | */ | |
84 | var that = this; |
|
84 | var that = this; | |
85 | this.setElement($('<button />') |
|
85 | this.setElement($('<button />') | |
86 | .addClass('btn btn-default') |
|
86 | .addClass('btn btn-default') | |
87 | .attr('type', 'button') |
|
87 | .attr('type', 'button') | |
88 | .on('click', function (e) { |
|
88 | .on('click', function (e) { | |
89 | e.preventDefault(); |
|
89 | e.preventDefault(); | |
90 | that.handle_click(); |
|
90 | that.handle_click(); | |
91 | })); |
|
91 | })); | |
92 | this.$el.attr("data-toggle", "tooltip"); |
|
92 | this.$el.attr("data-toggle", "tooltip"); | |
93 | this.model.on('change:button_style', function(model, value) { |
|
93 | this.model.on('change:button_style', function(model, value) { | |
94 | this.update_button_style(); |
|
94 | this.update_button_style(); | |
95 | }, this); |
|
95 | }, this); | |
96 | this.update_button_style(''); |
|
96 | this.update_button_style(''); | |
97 |
|
97 | |||
98 | this.update(); // Set defaults. |
|
98 | this.update(); // Set defaults. | |
99 | }, |
|
99 | }, | |
100 |
|
100 | |||
101 | update_button_style: function(previous_trait_value) { |
|
101 | update_button_style: function(previous_trait_value) { | |
102 | var class_map = { |
|
102 | var class_map = { | |
103 | primary: ['btn-primary'], |
|
103 | primary: ['btn-primary'], | |
104 | success: ['btn-success'], |
|
104 | success: ['btn-success'], | |
105 | info: ['btn-info'], |
|
105 | info: ['btn-info'], | |
106 | warning: ['btn-warning'], |
|
106 | warning: ['btn-warning'], | |
107 | danger: ['btn-danger'] |
|
107 | danger: ['btn-danger'] | |
108 | }; |
|
108 | }; | |
109 | this.update_mapped_classes(class_map, 'button_style', previous_trait_value); |
|
109 | this.update_mapped_classes(class_map, 'button_style', previous_trait_value); | |
110 | }, |
|
110 | }, | |
111 |
|
111 | |||
112 | update : function(options){ |
|
112 | update : function(options){ | |
113 | /** |
|
113 | /** | |
114 | * Update the contents of this view |
|
114 | * Update the contents of this view | |
115 | * |
|
115 | * | |
116 | * Called when the model is changed. The model may have been |
|
116 | * Called when the model is changed. The model may have been | |
117 | * changed by another view or by a state update from the back-end. |
|
117 | * changed by another view or by a state update from the back-end. | |
118 | */ |
|
118 | */ | |
119 | if (this.model.get('value')) { |
|
119 | if (this.model.get('value')) { | |
120 | this.$el.addClass('active'); |
|
120 | this.$el.addClass('active'); | |
121 | } else { |
|
121 | } else { | |
122 | this.$el.removeClass('active'); |
|
122 | this.$el.removeClass('active'); | |
123 | } |
|
123 | } | |
124 |
|
124 | |||
125 | if (options === undefined || options.updated_view != this) { |
|
125 | if (options === undefined || options.updated_view != this) { | |
126 |
|
126 | |||
127 | var disabled = this.model.get('disabled'); |
|
127 | var disabled = this.model.get('disabled'); | |
128 | this.$el.prop('disabled', disabled); |
|
128 | this.$el.prop('disabled', disabled); | |
129 |
|
129 | |||
130 | var description = this.model.get('description'); |
|
130 | var description = this.model.get('description'); | |
131 | this.$el.attr("title", this.model.get("tooltip")); |
|
131 | this.$el.attr("title", this.model.get("tooltip")); | |
132 |
|
|
132 | this.$el.text(description); | |
|
133 | var icon = this.model.get("icon"); | |||
|
134 | $('<i class="fa"></i>').prependTo(this.$el).addClass(icon); | |||
|
135 | if (description.trim().length === 0 && icon.trim().length ===0) { | |||
133 | this.$el.html(" "); // Preserve button height |
|
136 | this.$el.html(" "); // Preserve button height | |
134 | } else { |
|
|||
135 | this.$el.text(description); |
|
|||
136 | } |
|
137 | } | |
137 | } |
|
138 | } | |
138 | return ToggleButtonView.__super__.update.apply(this); |
|
139 | return ToggleButtonView.__super__.update.apply(this); | |
139 | }, |
|
140 | }, | |
140 |
|
141 | |||
141 | handle_click: function(e) { |
|
142 | handle_click: function(e) { | |
142 | /** |
|
143 | /** | |
143 | * Handles and validates user input. |
|
144 | * Handles and validates user input. | |
144 | * |
|
145 | * | |
145 | * Calling model.set will trigger all of the other views of the |
|
146 | * Calling model.set will trigger all of the other views of the | |
146 | * model to update. |
|
147 | * model to update. | |
147 | */ |
|
148 | */ | |
148 | var value = this.model.get('value'); |
|
149 | var value = this.model.get('value'); | |
149 | this.model.set('value', ! value, {updated_view: this}); |
|
150 | this.model.set('value', ! value, {updated_view: this}); | |
150 | this.touch(); |
|
151 | this.touch(); | |
151 | }, |
|
152 | }, | |
152 | }); |
|
153 | }); | |
153 |
|
154 | |||
154 | return { |
|
155 | return { | |
155 | 'CheckboxView': CheckboxView, |
|
156 | 'CheckboxView': CheckboxView, | |
156 | 'ToggleButtonView': ToggleButtonView, |
|
157 | 'ToggleButtonView': ToggleButtonView, | |
157 | }; |
|
158 | }; | |
158 | }); |
|
159 | }); |
@@ -1,77 +1,77 b'' | |||||
1 | // Copyright (c) IPython Development Team. |
|
1 | // Copyright (c) IPython Development Team. | |
2 | // Distributed under the terms of the Modified BSD License. |
|
2 | // Distributed under the terms of the Modified BSD License. | |
3 |
|
3 | |||
4 | define([ |
|
4 | define([ | |
5 | "widgets/js/widget", |
|
5 | "widgets/js/widget", | |
6 | "jquery", |
|
6 | "jquery", | |
7 | "bootstrap", |
|
7 | "bootstrap", | |
8 | ], function(widget, $){ |
|
8 | ], function(widget, $){ | |
9 |
|
9 | |||
10 | var ButtonView = widget.DOMWidgetView.extend({ |
|
10 | var ButtonView = widget.DOMWidgetView.extend({ | |
11 | render : function(){ |
|
11 | render : function(){ | |
12 | /** |
|
12 | /** | |
13 | * Called when view is rendered. |
|
13 | * Called when view is rendered. | |
14 | */ |
|
14 | */ | |
15 | this.setElement($("<button />") |
|
15 | this.setElement($("<button />") | |
16 | .addClass('btn btn-default')); |
|
16 | .addClass('btn btn-default')); | |
17 | this.$el.attr("data-toggle", "tooltip"); |
|
17 | this.$el.attr("data-toggle", "tooltip"); | |
18 | this.model.on('change:button_style', function(model, value) { |
|
18 | this.model.on('change:button_style', function(model, value) { | |
19 | this.update_button_style(); |
|
19 | this.update_button_style(); | |
20 | }, this); |
|
20 | }, this); | |
21 | this.update_button_style(''); |
|
21 | this.update_button_style(''); | |
22 |
|
22 | |||
23 | this.update(); // Set defaults. |
|
23 | this.update(); // Set defaults. | |
24 | }, |
|
24 | }, | |
25 |
|
25 | |||
26 | update : function(){ |
|
26 | update : function(){ | |
27 | /** |
|
27 | /** | |
28 | * Update the contents of this view |
|
28 | * Update the contents of this view | |
29 | * |
|
29 | * | |
30 | * Called when the model is changed. The model may have been |
|
30 | * Called when the model is changed. The model may have been | |
31 | * changed by another view or by a state update from the back-end. |
|
31 | * changed by another view or by a state update from the back-end. | |
32 | */ |
|
32 | */ | |
33 | var description = this.model.get('description'); |
|
33 | var description = this.model.get('description'); | |
34 | this.$el.attr("title", this.model.get("tooltip")); |
|
34 | this.$el.attr("title", this.model.get("tooltip")); | |
35 |
|
|
35 | this.$el.text(description); | |
|
36 | var icon = this.model.get("icon"); | |||
|
37 | $('<i class="fa"></i>').prependTo(this.$el).addClass(icon); | |||
|
38 | if (description.trim().length === 0 && icon.trim().length ===0) { | |||
36 | this.$el.html(" "); // Preserve button height |
|
39 | this.$el.html(" "); // Preserve button height | |
37 | } else { |
|
|||
38 | this.$el.text(description); |
|
|||
39 | } |
|
40 | } | |
40 |
|
||||
41 | if (this.model.get('disabled')) { |
|
41 | if (this.model.get('disabled')) { | |
42 | this.$el.attr('disabled','disabled'); |
|
42 | this.$el.attr('disabled','disabled'); | |
43 | } else { |
|
43 | } else { | |
44 | this.$el.removeAttr('disabled'); |
|
44 | this.$el.removeAttr('disabled'); | |
45 | } |
|
45 | } | |
46 |
|
46 | |||
47 | return ButtonView.__super__.update.apply(this); |
|
47 | return ButtonView.__super__.update.apply(this); | |
48 | }, |
|
48 | }, | |
49 |
|
49 | |||
50 | update_button_style: function(previous_trait_value) { |
|
50 | update_button_style: function(previous_trait_value) { | |
51 | var class_map = { |
|
51 | var class_map = { | |
52 | primary: ['btn-primary'], |
|
52 | primary: ['btn-primary'], | |
53 | success: ['btn-success'], |
|
53 | success: ['btn-success'], | |
54 | info: ['btn-info'], |
|
54 | info: ['btn-info'], | |
55 | warning: ['btn-warning'], |
|
55 | warning: ['btn-warning'], | |
56 | danger: ['btn-danger'] |
|
56 | danger: ['btn-danger'] | |
57 | }; |
|
57 | }; | |
58 | this.update_mapped_classes(class_map, 'button_style', previous_trait_value); |
|
58 | this.update_mapped_classes(class_map, 'button_style', previous_trait_value); | |
59 | }, |
|
59 | }, | |
60 |
|
60 | |||
61 | events: { |
|
61 | events: { | |
62 | // Dictionary of events and their handlers. |
|
62 | // Dictionary of events and their handlers. | |
63 | 'click': '_handle_click', |
|
63 | 'click': '_handle_click', | |
64 | }, |
|
64 | }, | |
65 |
|
65 | |||
66 | _handle_click: function(){ |
|
66 | _handle_click: function(){ | |
67 | /** |
|
67 | /** | |
68 | * Handles when the button is clicked. |
|
68 | * Handles when the button is clicked. | |
69 | */ |
|
69 | */ | |
70 | this.send({event: 'click'}); |
|
70 | this.send({event: 'click'}); | |
71 | }, |
|
71 | }, | |
72 | }); |
|
72 | }); | |
73 |
|
73 | |||
74 | return { |
|
74 | return { | |
75 | 'ButtonView': ButtonView, |
|
75 | 'ButtonView': ButtonView, | |
76 | }; |
|
76 | }; | |
77 | }); |
|
77 | }); |
@@ -1,92 +1,92 b'' | |||||
1 | // Test widget bool class |
|
1 | // Test widget bool class | |
2 | casper.notebook_test(function () { |
|
2 | casper.notebook_test(function () { | |
3 | "use strict"; |
|
3 | "use strict"; | |
4 |
|
4 | |||
5 | // Create a checkbox and togglebutton. |
|
5 | // Create a checkbox and togglebutton. | |
6 | var bool_index = this.append_cell( |
|
6 | var bool_index = this.append_cell( | |
7 | 'from IPython.html import widgets\n' + |
|
7 | 'from IPython.html import widgets\n' + | |
8 | 'from IPython.display import display, clear_output\n' + |
|
8 | 'from IPython.display import display, clear_output\n' + | |
9 | 'bool_widgets = [widgets.Checkbox(description="Title", value=True),\n' + |
|
9 | 'bool_widgets = [widgets.Checkbox(description="Title", value=True),\n' + | |
10 | ' widgets.ToggleButton(description="Title", value=True)]\n' + |
|
10 | ' widgets.ToggleButton(description="Title", value=True)]\n' + | |
11 | 'display(bool_widgets[0])\n' + |
|
11 | 'display(bool_widgets[0])\n' + | |
12 | 'display(bool_widgets[1])\n' + |
|
12 | 'display(bool_widgets[1])\n' + | |
13 | 'print("Success")'); |
|
13 | 'print("Success")'); | |
14 | this.execute_cell_then(bool_index, function(index){ |
|
14 | this.execute_cell_then(bool_index, function(index){ | |
15 | this.test.assertEquals(this.get_output_cell(index).text, 'Success\n', |
|
15 | this.test.assertEquals(this.get_output_cell(index).text, 'Success\n', | |
16 | 'Create bool widget cell executed with correct output.'); |
|
16 | 'Create bool widget cell executed with correct output.'); | |
17 | }); |
|
17 | }); | |
18 |
|
18 | |||
19 | // Wait for the widgets to actually display. |
|
19 | // Wait for the widgets to actually display. | |
20 | var widget_checkbox_selector = '.widget-area .widget-subarea .widget-hbox input'; |
|
20 | var widget_checkbox_selector = '.widget-area .widget-subarea .widget-hbox input'; | |
21 | var widget_togglebutton_selector = '.widget-area .widget-subarea button'; |
|
21 | var widget_togglebutton_selector = '.widget-area .widget-subarea button'; | |
22 | this.wait_for_element(bool_index, widget_checkbox_selector); |
|
22 | this.wait_for_element(bool_index, widget_checkbox_selector); | |
23 | this.wait_for_element(bool_index, widget_togglebutton_selector); |
|
23 | this.wait_for_element(bool_index, widget_togglebutton_selector); | |
24 |
|
24 | |||
25 | // Continue the tests. |
|
25 | // Continue the tests. | |
26 | this.then(function() { |
|
26 | this.then(function() { | |
27 | this.test.assert(this.cell_element_exists(bool_index, |
|
27 | this.test.assert(this.cell_element_exists(bool_index, | |
28 | '.widget-area .widget-subarea'), |
|
28 | '.widget-area .widget-subarea'), | |
29 | 'Widget subarea exists.'); |
|
29 | 'Widget subarea exists.'); | |
30 |
|
30 | |||
31 | this.test.assert(this.cell_element_exists(bool_index, |
|
31 | this.test.assert(this.cell_element_exists(bool_index, | |
32 | widget_checkbox_selector), |
|
32 | widget_checkbox_selector), | |
33 | 'Checkbox exists.'); |
|
33 | 'Checkbox exists.'); | |
34 |
|
34 | |||
35 | this.test.assert(this.cell_element_function(bool_index, |
|
35 | this.test.assert(this.cell_element_function(bool_index, | |
36 | widget_checkbox_selector, 'prop', ['checked']), |
|
36 | widget_checkbox_selector, 'prop', ['checked']), | |
37 | 'Checkbox is checked.'); |
|
37 | 'Checkbox is checked.'); | |
38 |
|
38 | |||
39 | this.test.assert(this.cell_element_exists(bool_index, |
|
39 | this.test.assert(this.cell_element_exists(bool_index, | |
40 | '.widget-area .widget-subarea .widget-hbox .widget-label'), |
|
40 | '.widget-area .widget-subarea .widget-hbox .widget-label'), | |
41 | 'Checkbox label exists.'); |
|
41 | 'Checkbox label exists.'); | |
42 |
|
42 | |||
43 | this.test.assert(this.cell_element_function(bool_index, |
|
43 | this.test.assert(this.cell_element_function(bool_index, | |
44 | '.widget-area .widget-subarea .widget-hbox .widget-label', 'html')=="Title", |
|
44 | '.widget-area .widget-subarea .widget-hbox .widget-label', 'html')=="Title", | |
45 | 'Checkbox labeled correctly.'); |
|
45 | 'Checkbox labeled correctly.'); | |
46 |
|
46 | |||
47 | this.test.assert(this.cell_element_exists(bool_index, |
|
47 | this.test.assert(this.cell_element_exists(bool_index, | |
48 | widget_togglebutton_selector), |
|
48 | widget_togglebutton_selector), | |
49 | 'Toggle button exists.'); |
|
49 | 'Toggle button exists.'); | |
50 |
|
50 | |||
51 | this.test.assert(this.cell_element_function(bool_index, |
|
51 | this.test.assert(this.cell_element_function(bool_index, | |
52 |
widget_togglebutton_selector, 'html')== |
|
52 | widget_togglebutton_selector, 'html')=='<i class="fa"></i>Title', | |
53 | 'Toggle button labeled correctly.'); |
|
53 | 'Toggle button labeled correctly.'); | |
54 |
|
54 | |||
55 | this.test.assert(this.cell_element_function(bool_index, |
|
55 | this.test.assert(this.cell_element_function(bool_index, | |
56 | widget_togglebutton_selector, 'hasClass', ['active']), |
|
56 | widget_togglebutton_selector, 'hasClass', ['active']), | |
57 | 'Toggle button is toggled.'); |
|
57 | 'Toggle button is toggled.'); | |
58 | }); |
|
58 | }); | |
59 |
|
59 | |||
60 | // Try changing the state of the widgets programatically. |
|
60 | // Try changing the state of the widgets programatically. | |
61 | var index = this.append_cell( |
|
61 | var index = this.append_cell( | |
62 | 'bool_widgets[0].value = False\n' + |
|
62 | 'bool_widgets[0].value = False\n' + | |
63 | 'bool_widgets[1].value = False\n' + |
|
63 | 'bool_widgets[1].value = False\n' + | |
64 | 'print("Success")'); |
|
64 | 'print("Success")'); | |
65 | this.execute_cell_then(index, function(index){ |
|
65 | this.execute_cell_then(index, function(index){ | |
66 | this.test.assertEquals(this.get_output_cell(index).text, 'Success\n', |
|
66 | this.test.assertEquals(this.get_output_cell(index).text, 'Success\n', | |
67 | 'Change bool widget value cell executed with correct output.'); |
|
67 | 'Change bool widget value cell executed with correct output.'); | |
68 |
|
68 | |||
69 | this.test.assert(! this.cell_element_function(bool_index, |
|
69 | this.test.assert(! this.cell_element_function(bool_index, | |
70 | widget_checkbox_selector, 'prop', ['checked']), |
|
70 | widget_checkbox_selector, 'prop', ['checked']), | |
71 | 'Checkbox is not checked. (1)'); |
|
71 | 'Checkbox is not checked. (1)'); | |
72 |
|
72 | |||
73 | this.test.assert(! this.cell_element_function(bool_index, |
|
73 | this.test.assert(! this.cell_element_function(bool_index, | |
74 | widget_togglebutton_selector, 'hasClass', ['active']), |
|
74 | widget_togglebutton_selector, 'hasClass', ['active']), | |
75 | 'Toggle button is not toggled. (1)'); |
|
75 | 'Toggle button is not toggled. (1)'); | |
76 |
|
76 | |||
77 | // Try toggling the bool by clicking on the checkbox. |
|
77 | // Try toggling the bool by clicking on the checkbox. | |
78 | this.cell_element_function(bool_index, widget_checkbox_selector, 'click'); |
|
78 | this.cell_element_function(bool_index, widget_checkbox_selector, 'click'); | |
79 |
|
79 | |||
80 | this.test.assert(this.cell_element_function(bool_index, |
|
80 | this.test.assert(this.cell_element_function(bool_index, | |
81 | widget_checkbox_selector, 'prop', ['checked']), |
|
81 | widget_checkbox_selector, 'prop', ['checked']), | |
82 | 'Checkbox is checked. (2)'); |
|
82 | 'Checkbox is checked. (2)'); | |
83 |
|
83 | |||
84 | // Try toggling the bool by clicking on the toggle button. |
|
84 | // Try toggling the bool by clicking on the toggle button. | |
85 | this.cell_element_function(bool_index, widget_togglebutton_selector, 'click'); |
|
85 | this.cell_element_function(bool_index, widget_togglebutton_selector, 'click'); | |
86 |
|
86 | |||
87 | this.test.assert(this.cell_element_function(bool_index, |
|
87 | this.test.assert(this.cell_element_function(bool_index, | |
88 | widget_togglebutton_selector, 'hasClass', ['active']), |
|
88 | widget_togglebutton_selector, 'hasClass', ['active']), | |
89 | 'Toggle button is toggled. (3)'); |
|
89 | 'Toggle button is toggled. (3)'); | |
90 |
|
90 | |||
91 | }); |
|
91 | }); | |
92 | }); |
|
92 | }); |
@@ -1,48 +1,48 b'' | |||||
1 | // Test widget button class |
|
1 | // Test widget button class | |
2 | casper.notebook_test(function () { |
|
2 | casper.notebook_test(function () { | |
3 | var button_index = this.append_cell( |
|
3 | var button_index = this.append_cell( | |
4 | 'from IPython.html import widgets\n' + |
|
4 | 'from IPython.html import widgets\n' + | |
5 | 'from IPython.display import display, clear_output\n' + |
|
5 | 'from IPython.display import display, clear_output\n' + | |
6 | 'button = widgets.Button(description="Title")\n' + |
|
6 | 'button = widgets.Button(description="Title")\n' + | |
7 | 'display(button)\n' + |
|
7 | 'display(button)\n' + | |
8 | 'print("Success")\n' + |
|
8 | 'print("Success")\n' + | |
9 | 'def handle_click(sender):\n' + |
|
9 | 'def handle_click(sender):\n' + | |
10 | ' display("Clicked")\n' + |
|
10 | ' display("Clicked")\n' + | |
11 | 'button.on_click(handle_click)'); |
|
11 | 'button.on_click(handle_click)'); | |
12 | this.execute_cell_then(button_index, function(index){ |
|
12 | this.execute_cell_then(button_index, function(index){ | |
13 | this.test.assertEquals(this.get_output_cell(index).text, 'Success\n', |
|
13 | this.test.assertEquals(this.get_output_cell(index).text, 'Success\n', | |
14 | 'Create button cell executed with correct output.'); |
|
14 | 'Create button cell executed with correct output.'); | |
15 | }); |
|
15 | }); | |
16 |
|
16 | |||
17 | // Wait for the widgets to actually display. |
|
17 | // Wait for the widgets to actually display. | |
18 | var widget_button_selector = '.widget-area .widget-subarea button'; |
|
18 | var widget_button_selector = '.widget-area .widget-subarea button'; | |
19 | this.wait_for_element(button_index, widget_button_selector); |
|
19 | this.wait_for_element(button_index, widget_button_selector); | |
20 |
|
20 | |||
21 | // Continue with the tests. |
|
21 | // Continue with the tests. | |
22 | this.then(function() { |
|
22 | this.then(function() { | |
23 | this.test.assert(this.cell_element_exists(button_index, |
|
23 | this.test.assert(this.cell_element_exists(button_index, | |
24 | '.widget-area .widget-subarea'), |
|
24 | '.widget-area .widget-subarea'), | |
25 | 'Widget subarea exists.'); |
|
25 | 'Widget subarea exists.'); | |
26 |
|
26 | |||
27 | this.test.assert(this.cell_element_exists(button_index, |
|
27 | this.test.assert(this.cell_element_exists(button_index, | |
28 | widget_button_selector), |
|
28 | widget_button_selector), | |
29 | 'Widget button exists.'); |
|
29 | 'Widget button exists.'); | |
30 |
|
30 | |||
31 | this.test.assert(this.cell_element_function(button_index, |
|
31 | this.test.assert(this.cell_element_function(button_index, | |
32 | widget_button_selector, 'html')=='Title', |
|
32 | widget_button_selector, 'html')=='<i class="fa"></i>Title', | |
33 | 'Set button description.'); |
|
33 | 'Set button description.'); | |
34 |
|
34 | |||
35 | this.cell_element_function(button_index, |
|
35 | this.cell_element_function(button_index, | |
36 | widget_button_selector, 'click'); |
|
36 | widget_button_selector, 'click'); | |
37 | }); |
|
37 | }); | |
38 |
|
38 | |||
39 | this.wait_for_output(button_index, 1); |
|
39 | this.wait_for_output(button_index, 1); | |
40 |
|
40 | |||
41 | this.then(function () { |
|
41 | this.then(function () { | |
42 | var warning_text = this.get_output_cell(button_index, 1).text; |
|
42 | var warning_text = this.get_output_cell(button_index, 1).text; | |
43 | this.test.assertNotEquals(warning_text.indexOf('Warning'), -1, |
|
43 | this.test.assertNotEquals(warning_text.indexOf('Warning'), -1, | |
44 | 'Importing widgets show a warning'); |
|
44 | 'Importing widgets show a warning'); | |
45 | this.test.assertEquals(this.get_output_cell(button_index, 2).data['text/plain'], "'Clicked'", |
|
45 | this.test.assertEquals(this.get_output_cell(button_index, 2).data['text/plain'], "'Clicked'", | |
46 | 'Button click event fires.'); |
|
46 | 'Button click event fires.'); | |
47 | }); |
|
47 | }); | |
48 | }); |
|
48 | }); |
@@ -1,71 +1,76 b'' | |||||
1 | """Bool class. |
|
1 | """Bool class. | |
2 |
|
2 | |||
3 | Represents a boolean using a widget. |
|
3 | Represents a boolean using a widget. | |
4 | """ |
|
4 | """ | |
5 | #----------------------------------------------------------------------------- |
|
5 | #----------------------------------------------------------------------------- | |
6 | # Copyright (c) 2013, the IPython Development Team. |
|
6 | # Copyright (c) 2013, the IPython Development Team. | |
7 | # |
|
7 | # | |
8 | # Distributed under the terms of the Modified BSD License. |
|
8 | # Distributed under the terms of the Modified BSD License. | |
9 | # |
|
9 | # | |
10 | # The full license is in the file COPYING.txt, distributed with this software. |
|
10 | # The full license is in the file COPYING.txt, distributed with this software. | |
11 | #----------------------------------------------------------------------------- |
|
11 | #----------------------------------------------------------------------------- | |
12 |
|
12 | |||
13 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
14 | # Imports |
|
14 | # Imports | |
15 | #----------------------------------------------------------------------------- |
|
15 | #----------------------------------------------------------------------------- | |
16 | from .widget import DOMWidget, register |
|
16 | from .widget import DOMWidget, register | |
17 | from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum |
|
17 | from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum | |
18 | from IPython.utils.warn import DeprecatedClass |
|
18 | from IPython.utils.warn import DeprecatedClass | |
19 |
|
19 | |||
20 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
21 | # Classes |
|
21 | # Classes | |
22 | #----------------------------------------------------------------------------- |
|
22 | #----------------------------------------------------------------------------- | |
23 | class _Bool(DOMWidget): |
|
23 | class _Bool(DOMWidget): | |
24 | """A base class for creating widgets that represent booleans.""" |
|
24 | """A base class for creating widgets that represent booleans.""" | |
25 | value = Bool(False, help="Bool value", sync=True) |
|
25 | value = Bool(False, help="Bool value", sync=True) | |
26 | description = Unicode('', help="Description of the boolean (label).", sync=True) |
|
26 | description = Unicode('', help="Description of the boolean (label).", sync=True) | |
27 | disabled = Bool(False, help="Enable or disable user changes.", sync=True) |
|
27 | disabled = Bool(False, help="Enable or disable user changes.", sync=True) | |
28 |
|
28 | |||
29 | def __init__(self, value=None, **kwargs): |
|
29 | def __init__(self, value=None, **kwargs): | |
30 | if value is not None: |
|
30 | if value is not None: | |
31 | kwargs['value'] = value |
|
31 | kwargs['value'] = value | |
32 | super(_Bool, self).__init__(**kwargs) |
|
32 | super(_Bool, self).__init__(**kwargs) | |
33 |
|
33 | |||
34 | @register('IPython.Checkbox') |
|
34 | @register('IPython.Checkbox') | |
35 | class Checkbox(_Bool): |
|
35 | class Checkbox(_Bool): | |
36 | """Displays a boolean `value` in the form of a checkbox. |
|
36 | """Displays a boolean `value` in the form of a checkbox. | |
37 |
|
37 | |||
38 | Parameters |
|
38 | Parameters | |
39 | ---------- |
|
39 | ---------- | |
40 | value : {True,False} |
|
40 | value : {True,False} | |
41 | value of the checkbox: True-checked, False-unchecked |
|
41 | value of the checkbox: True-checked, False-unchecked | |
42 | description : str |
|
42 | description : str | |
43 | description displayed next to the checkbox |
|
43 | description displayed next to the checkbox | |
44 | """ |
|
44 | """ | |
45 | _view_name = Unicode('CheckboxView', sync=True) |
|
45 | _view_name = Unicode('CheckboxView', sync=True) | |
46 |
|
46 | |||
47 |
|
47 | |||
48 | @register('IPython.ToggleButton') |
|
48 | @register('IPython.ToggleButton') | |
49 | class ToggleButton(_Bool): |
|
49 | class ToggleButton(_Bool): | |
50 | """Displays a boolean `value` in the form of a toggle button. |
|
50 | """Displays a boolean `value` in the form of a toggle button. | |
51 |
|
51 | |||
52 | Parameters |
|
52 | Parameters | |
53 | ---------- |
|
53 | ---------- | |
54 | value : {True,False} |
|
54 | value : {True,False} | |
55 | value of the toggle button: True-pressed, False-unpressed |
|
55 | value of the toggle button: True-pressed, False-unpressed | |
56 | description : str |
|
56 | description : str | |
57 | description displayed next to the button |
|
57 | description displayed next to the button | |
|
58 | tooltip: str | |||
|
59 | tooltip caption of the toggle button | |||
|
60 | icon: str | |||
|
61 | font-awesome icon name | |||
58 | """ |
|
62 | """ | |
59 |
|
63 | |||
60 | _view_name = Unicode('ToggleButtonView', sync=True) |
|
64 | _view_name = Unicode('ToggleButtonView', sync=True) | |
61 | tooltip = Unicode(help="Tooltip caption of the toggle button.", sync=True) |
|
65 | tooltip = Unicode(help="Tooltip caption of the toggle button.", sync=True) | |
|
66 | icon = Unicode('', help= "Font-awesome icon.", sync=True) | |||
62 |
|
67 | |||
63 | button_style = CaselessStrEnum( |
|
68 | button_style = CaselessStrEnum( | |
64 | values=['primary', 'success', 'info', 'warning', 'danger', ''], |
|
69 | values=['primary', 'success', 'info', 'warning', 'danger', ''], | |
65 | default_value='', allow_none=True, sync=True, help="""Use a |
|
70 | default_value='', allow_none=True, sync=True, help="""Use a | |
66 | predefined styling for the button.""") |
|
71 | predefined styling for the button.""") | |
67 |
|
72 | |||
68 |
|
73 | |||
69 | # Remove in IPython 4.0 |
|
74 | # Remove in IPython 4.0 | |
70 | CheckboxWidget = DeprecatedClass(Checkbox, 'CheckboxWidget') |
|
75 | CheckboxWidget = DeprecatedClass(Checkbox, 'CheckboxWidget') | |
71 | ToggleButtonWidget = DeprecatedClass(ToggleButton, 'ToggleButtonWidget') |
|
76 | ToggleButtonWidget = DeprecatedClass(ToggleButton, 'ToggleButtonWidget') |
@@ -1,72 +1,82 b'' | |||||
1 | """Button class. |
|
1 | """Button class. | |
2 |
|
2 | |||
3 | Represents a button in the frontend using a widget. Allows user to listen for |
|
3 | Represents a button in the frontend using a widget. Allows user to listen for | |
4 | click events on the button and trigger backend code when the clicks are fired. |
|
4 | click events on the button and trigger backend code when the clicks are fired. | |
5 | """ |
|
5 | """ | |
6 | #----------------------------------------------------------------------------- |
|
6 | #----------------------------------------------------------------------------- | |
7 | # Copyright (c) 2013, the IPython Development Team. |
|
7 | # Copyright (c) 2013, the IPython Development Team. | |
8 | # |
|
8 | # | |
9 | # Distributed under the terms of the Modified BSD License. |
|
9 | # Distributed under the terms of the Modified BSD License. | |
10 | # |
|
10 | # | |
11 | # The full license is in the file COPYING.txt, distributed with this software. |
|
11 | # The full license is in the file COPYING.txt, distributed with this software. | |
12 | #----------------------------------------------------------------------------- |
|
12 | #----------------------------------------------------------------------------- | |
13 |
|
13 | |||
14 | #----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 | # Imports |
|
15 | # Imports | |
16 | #----------------------------------------------------------------------------- |
|
16 | #----------------------------------------------------------------------------- | |
17 | from .widget import DOMWidget, CallbackDispatcher, register |
|
17 | from .widget import DOMWidget, CallbackDispatcher, register | |
18 | from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum |
|
18 | from IPython.utils.traitlets import Unicode, Bool, CaselessStrEnum | |
19 | from IPython.utils.warn import DeprecatedClass |
|
19 | from IPython.utils.warn import DeprecatedClass | |
20 |
|
20 | |||
21 | #----------------------------------------------------------------------------- |
|
21 | #----------------------------------------------------------------------------- | |
22 | # Classes |
|
22 | # Classes | |
23 | #----------------------------------------------------------------------------- |
|
23 | #----------------------------------------------------------------------------- | |
24 | @register('IPython.Button') |
|
24 | @register('IPython.Button') | |
25 | class Button(DOMWidget): |
|
25 | class Button(DOMWidget): | |
26 | """Button widget. |
|
26 | """Button widget. | |
|
27 | This widget has an `on_click` method that allows you to listen for the | |||
|
28 | user clicking on the button. The click event itself is stateless. | |||
27 |
|
29 | |||
28 | This widget has an `on_click` method that allows you to listen for the |
|
30 | Parameters | |
29 | user clicking on the button. The click event itself is stateless.""" |
|
31 | ---------- | |
|
32 | description : str | |||
|
33 | description displayed next to the button | |||
|
34 | tooltip: str | |||
|
35 | tooltip caption of the toggle button | |||
|
36 | icon: str | |||
|
37 | font-awesome icon name | |||
|
38 | """ | |||
30 | _view_name = Unicode('ButtonView', sync=True) |
|
39 | _view_name = Unicode('ButtonView', sync=True) | |
31 |
|
40 | |||
32 | # Keys |
|
41 | # Keys | |
33 | description = Unicode('', help="Button label.", sync=True) |
|
42 | description = Unicode('', help="Button label.", sync=True) | |
34 | tooltip = Unicode(help="Tooltip caption of the button.", sync=True) |
|
43 | tooltip = Unicode(help="Tooltip caption of the button.", sync=True) | |
35 | disabled = Bool(False, help="Enable or disable user changes.", sync=True) |
|
44 | disabled = Bool(False, help="Enable or disable user changes.", sync=True) | |
|
45 | icon = Unicode('', help= "Font-awesome icon.", sync=True) | |||
36 |
|
46 | |||
37 | button_style = CaselessStrEnum( |
|
47 | button_style = CaselessStrEnum( | |
38 | values=['primary', 'success', 'info', 'warning', 'danger', ''], |
|
48 | values=['primary', 'success', 'info', 'warning', 'danger', ''], | |
39 | default_value='', allow_none=True, sync=True, help="""Use a |
|
49 | default_value='', allow_none=True, sync=True, help="""Use a | |
40 | predefined styling for the button.""") |
|
50 | predefined styling for the button.""") | |
41 |
|
51 | |||
42 | def __init__(self, **kwargs): |
|
52 | def __init__(self, **kwargs): | |
43 | """Constructor""" |
|
53 | """Constructor""" | |
44 | super(Button, self).__init__(**kwargs) |
|
54 | super(Button, self).__init__(**kwargs) | |
45 | self._click_handlers = CallbackDispatcher() |
|
55 | self._click_handlers = CallbackDispatcher() | |
46 | self.on_msg(self._handle_button_msg) |
|
56 | self.on_msg(self._handle_button_msg) | |
47 |
|
57 | |||
48 | def on_click(self, callback, remove=False): |
|
58 | def on_click(self, callback, remove=False): | |
49 | """Register a callback to execute when the button is clicked. |
|
59 | """Register a callback to execute when the button is clicked. | |
50 |
|
60 | |||
51 | The callback will be called with one argument, |
|
61 | The callback will be called with one argument, | |
52 | the clicked button widget instance. |
|
62 | the clicked button widget instance. | |
53 |
|
63 | |||
54 | Parameters |
|
64 | Parameters | |
55 | ---------- |
|
65 | ---------- | |
56 | remove : bool (optional) |
|
66 | remove : bool (optional) | |
57 | Set to true to remove the callback from the list of callbacks.""" |
|
67 | Set to true to remove the callback from the list of callbacks.""" | |
58 | self._click_handlers.register_callback(callback, remove=remove) |
|
68 | self._click_handlers.register_callback(callback, remove=remove) | |
59 |
|
69 | |||
60 | def _handle_button_msg(self, _, content): |
|
70 | def _handle_button_msg(self, _, content): | |
61 | """Handle a msg from the front-end. |
|
71 | """Handle a msg from the front-end. | |
62 |
|
72 | |||
63 | Parameters |
|
73 | Parameters | |
64 | ---------- |
|
74 | ---------- | |
65 | content: dict |
|
75 | content: dict | |
66 | Content of the msg.""" |
|
76 | Content of the msg.""" | |
67 | if content.get('event', '') == 'click': |
|
77 | if content.get('event', '') == 'click': | |
68 | self._click_handlers(self) |
|
78 | self._click_handlers(self) | |
69 |
|
79 | |||
70 |
|
80 | |||
71 | # Remove in IPython 4.0 |
|
81 | # Remove in IPython 4.0 | |
72 | ButtonWidget = DeprecatedClass(Button, 'ButtonWidget') |
|
82 | ButtonWidget = DeprecatedClass(Button, 'ButtonWidget') |
General Comments 0
You need to be logged in to leave comments.
Login now