##// END OF EJS Templates
Merge pull request #5652 from jhamrick/placeholder...
Jonathan Frederic -
r16352:04f4cf16 merge
parent child Browse files
Show More
@@ -0,0 +1,3
1 * `TextWidget` and `TextareaWidget` objects now include a
2 `placeholder` attribute, for displaying placeholder text before the
3 user has typed anything.
@@ -1,222 +1,246
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2013 The IPython Development Team
2 // Copyright (C) 2013 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 // StringWidget
9 // StringWidget
10 //============================================================================
10 //============================================================================
11
11
12 /**
12 /**
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 **/
15 **/
16
16
17 define(["widgets/js/widget"], function(WidgetManager){
17 define(["widgets/js/widget"], function(WidgetManager){
18
18
19 var HTMLView = IPython.DOMWidgetView.extend({
19 var HTMLView = IPython.DOMWidgetView.extend({
20 render : function(){
20 render : function(){
21 // Called when view is rendered.
21 // Called when view is rendered.
22 this.update(); // Set defaults.
22 this.update(); // Set defaults.
23 },
23 },
24
24
25 update : function(){
25 update : function(){
26 // Update the contents of this view
26 // Update the contents of this view
27 //
27 //
28 // Called when the model is changed. The model may have been
28 // Called when the model is changed. The model may have been
29 // changed by another view or by a state update from the back-end.
29 // changed by another view or by a state update from the back-end.
30 this.$el.html(this.model.get('value')); // CAUTION! .html(...) CALL MANDITORY!!!
30 this.$el.html(this.model.get('value')); // CAUTION! .html(...) CALL MANDITORY!!!
31 return HTMLView.__super__.update.apply(this);
31 return HTMLView.__super__.update.apply(this);
32 },
32 },
33 });
33 });
34 WidgetManager.register_widget_view('HTMLView', HTMLView);
34 WidgetManager.register_widget_view('HTMLView', HTMLView);
35
35
36
36
37 var LatexView = IPython.DOMWidgetView.extend({
37 var LatexView = IPython.DOMWidgetView.extend({
38 render : function(){
38 render : function(){
39 // Called when view is rendered.
39 // Called when view is rendered.
40 this.update(); // Set defaults.
40 this.update(); // Set defaults.
41 },
41 },
42
42
43 update : function(){
43 update : function(){
44 // Update the contents of this view
44 // Update the contents of this view
45 //
45 //
46 // Called when the model is changed. The model may have been
46 // Called when the model is changed. The model may have been
47 // changed by another view or by a state update from the back-end.
47 // changed by another view or by a state update from the back-end.
48 this.$el.text(this.model.get('value'));
48 this.$el.text(this.model.get('value'));
49 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$el.get(0)]);
49 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$el.get(0)]);
50
50
51 return LatexView.__super__.update.apply(this);
51 return LatexView.__super__.update.apply(this);
52 },
52 },
53 });
53 });
54 WidgetManager.register_widget_view('LatexView', LatexView);
54 WidgetManager.register_widget_view('LatexView', LatexView);
55
55
56
56
57 var TextareaView = IPython.DOMWidgetView.extend({
57 var TextareaView = IPython.DOMWidgetView.extend({
58 render: function(){
58 render: function(){
59 // Called when view is rendered.
59 // Called when view is rendered.
60 this.$el
60 this.$el
61 .addClass('widget-hbox');
61 .addClass('widget-hbox');
62 this.$label = $('<div />')
62 this.$label = $('<div />')
63 .appendTo(this.$el)
63 .appendTo(this.$el)
64 .addClass('widget-hlabel')
64 .addClass('widget-hlabel')
65 .hide();
65 .hide();
66 this.$textbox = $('<textarea />')
66 this.$textbox = $('<textarea />')
67 .attr('rows', 5)
67 .attr('rows', 5)
68 .addClass('widget-text')
68 .addClass('widget-text')
69 .appendTo(this.$el);
69 .appendTo(this.$el);
70 this.$el_to_style = this.$textbox; // Set default element to style
70 this.$el_to_style = this.$textbox; // Set default element to style
71 this.update(); // Set defaults.
71 this.update(); // Set defaults.
72
72
73 this.model.on('msg:custom', $.proxy(this._handle_textarea_msg, this));
73 this.model.on('msg:custom', $.proxy(this._handle_textarea_msg, this));
74 this.model.on('change:placeholder', function(model, value, options) {
75 this.update_placeholder(value);
76 }, this);
77
78 this.update_placeholder();
74 },
79 },
75
80
76 _handle_textarea_msg: function (content){
81 _handle_textarea_msg: function (content){
77 // Handle when a custom msg is recieved from the back-end.
82 // Handle when a custom msg is recieved from the back-end.
78 if (content.method == "scroll_to_bottom") {
83 if (content.method == "scroll_to_bottom") {
79 this.scroll_to_bottom();
84 this.scroll_to_bottom();
80 }
85 }
81 },
86 },
82
87
88 update_placeholder: function(value) {
89 if (!value) {
90 value = this.model.get('placeholder');
91 }
92 this.$textbox.attr('placeholder', value);
93 },
94
83 scroll_to_bottom: function (){
95 scroll_to_bottom: function (){
84 // Scroll the text-area view to the bottom.
96 // Scroll the text-area view to the bottom.
85 this.$textbox.scrollTop(this.$textbox[0].scrollHeight);
97 this.$textbox.scrollTop(this.$textbox[0].scrollHeight);
86 },
98 },
87
99
88 update: function(options){
100 update: function(options){
89 // Update the contents of this view
101 // Update the contents of this view
90 //
102 //
91 // Called when the model is changed. The model may have been
103 // Called when the model is changed. The model may have been
92 // changed by another view or by a state update from the back-end.
104 // changed by another view or by a state update from the back-end.
93 if (options === undefined || options.updated_view != this) {
105 if (options === undefined || options.updated_view != this) {
94 this.$textbox.val(this.model.get('value'));
106 this.$textbox.val(this.model.get('value'));
95
107
96 var disabled = this.model.get('disabled');
108 var disabled = this.model.get('disabled');
97 this.$textbox.prop('disabled', disabled);
109 this.$textbox.prop('disabled', disabled);
98
110
99 var description = this.model.get('description');
111 var description = this.model.get('description');
100 if (description.length === 0) {
112 if (description.length === 0) {
101 this.$label.hide();
113 this.$label.hide();
102 } else {
114 } else {
103 this.$label.text(description);
115 this.$label.text(description);
104 this.$label.show();
116 this.$label.show();
105 }
117 }
106 }
118 }
107 return TextareaView.__super__.update.apply(this);
119 return TextareaView.__super__.update.apply(this);
108 },
120 },
109
121
110 events: {
122 events: {
111 // Dictionary of events and their handlers.
123 // Dictionary of events and their handlers.
112 "keyup textarea" : "handleChanging",
124 "keyup textarea" : "handleChanging",
113 "paste textarea" : "handleChanging",
125 "paste textarea" : "handleChanging",
114 "cut textarea" : "handleChanging"
126 "cut textarea" : "handleChanging"
115 },
127 },
116
128
117 handleChanging: function(e) {
129 handleChanging: function(e) {
118 // Handles and validates user input.
130 // Handles and validates user input.
119
131
120 // Calling model.set will trigger all of the other views of the
132 // Calling model.set will trigger all of the other views of the
121 // model to update.
133 // model to update.
122 this.model.set('value', e.target.value, {updated_view: this});
134 this.model.set('value', e.target.value, {updated_view: this});
123 this.touch();
135 this.touch();
124 },
136 },
125 });
137 });
126 WidgetManager.register_widget_view('TextareaView', TextareaView);
138 WidgetManager.register_widget_view('TextareaView', TextareaView);
127
139
128
140
129 var TextView = IPython.DOMWidgetView.extend({
141 var TextView = IPython.DOMWidgetView.extend({
130 render: function(){
142 render: function(){
131 // Called when view is rendered.
143 // Called when view is rendered.
132 this.$el
144 this.$el
133 .addClass('widget-hbox-single');
145 .addClass('widget-hbox-single');
134 this.$label = $('<div />')
146 this.$label = $('<div />')
135 .addClass('widget-hlabel')
147 .addClass('widget-hlabel')
136 .appendTo(this.$el)
148 .appendTo(this.$el)
137 .hide();
149 .hide();
138 this.$textbox = $('<input type="text" />')
150 this.$textbox = $('<input type="text" />')
139 .addClass('input')
151 .addClass('input')
140 .addClass('widget-text')
152 .addClass('widget-text')
141 .appendTo(this.$el);
153 .appendTo(this.$el);
142 this.$el_to_style = this.$textbox; // Set default element to style
154 this.$el_to_style = this.$textbox; // Set default element to style
143 this.update(); // Set defaults.
155 this.update(); // Set defaults.
156 this.model.on('change:placeholder', function(model, value, options) {
157 this.update_placeholder(value);
158 }, this);
159
160 this.update_placeholder();
161 },
162
163 update_placeholder: function(value) {
164 if (!value) {
165 value = this.model.get('placeholder');
166 }
167 this.$textbox.attr('placeholder', value);
144 },
168 },
145
169
146 update: function(options){
170 update: function(options){
147 // Update the contents of this view
171 // Update the contents of this view
148 //
172 //
149 // Called when the model is changed. The model may have been
173 // Called when the model is changed. The model may have been
150 // changed by another view or by a state update from the back-end.
174 // changed by another view or by a state update from the back-end.
151 if (options === undefined || options.updated_view != this) {
175 if (options === undefined || options.updated_view != this) {
152 if (this.$textbox.val() != this.model.get('value')) {
176 if (this.$textbox.val() != this.model.get('value')) {
153 this.$textbox.val(this.model.get('value'));
177 this.$textbox.val(this.model.get('value'));
154 }
178 }
155
179
156 var disabled = this.model.get('disabled');
180 var disabled = this.model.get('disabled');
157 this.$textbox.prop('disabled', disabled);
181 this.$textbox.prop('disabled', disabled);
158
182
159 var description = this.model.get('description');
183 var description = this.model.get('description');
160 if (description.length === 0) {
184 if (description.length === 0) {
161 this.$label.hide();
185 this.$label.hide();
162 } else {
186 } else {
163 this.$label.text(description);
187 this.$label.text(description);
164 this.$label.show();
188 this.$label.show();
165 }
189 }
166 }
190 }
167 return TextView.__super__.update.apply(this);
191 return TextView.__super__.update.apply(this);
168 },
192 },
169
193
170 events: {
194 events: {
171 // Dictionary of events and their handlers.
195 // Dictionary of events and their handlers.
172 "keyup input" : "handleChanging",
196 "keyup input" : "handleChanging",
173 "paste input" : "handleChanging",
197 "paste input" : "handleChanging",
174 "cut input" : "handleChanging",
198 "cut input" : "handleChanging",
175 "keypress input" : "handleKeypress",
199 "keypress input" : "handleKeypress",
176 "blur input" : "handleBlur",
200 "blur input" : "handleBlur",
177 "focusout input" : "handleFocusOut"
201 "focusout input" : "handleFocusOut"
178 },
202 },
179
203
180 handleChanging: function(e) {
204 handleChanging: function(e) {
181 // Handles user input.
205 // Handles user input.
182
206
183 // Calling model.set will trigger all of the other views of the
207 // Calling model.set will trigger all of the other views of the
184 // model to update.
208 // model to update.
185 this.model.set('value', e.target.value, {updated_view: this});
209 this.model.set('value', e.target.value, {updated_view: this});
186 this.touch();
210 this.touch();
187 },
211 },
188
212
189 handleKeypress: function(e) {
213 handleKeypress: function(e) {
190 // Handles text submition
214 // Handles text submition
191 if (e.keyCode == 13) { // Return key
215 if (e.keyCode == 13) { // Return key
192 this.send({event: 'submit'});
216 this.send({event: 'submit'});
193 event.stopPropagation();
217 event.stopPropagation();
194 event.preventDefault();
218 event.preventDefault();
195 return false;
219 return false;
196 }
220 }
197 },
221 },
198
222
199 handleBlur: function(e) {
223 handleBlur: function(e) {
200 // Prevent a blur from firing if the blur was not user intended.
224 // Prevent a blur from firing if the blur was not user intended.
201 // This is a workaround for the return-key focus loss bug.
225 // This is a workaround for the return-key focus loss bug.
202 // TODO: Is the original bug actually a fault of the keyboard
226 // TODO: Is the original bug actually a fault of the keyboard
203 // manager?
227 // manager?
204 if (e.relatedTarget === null) {
228 if (e.relatedTarget === null) {
205 event.stopPropagation();
229 event.stopPropagation();
206 event.preventDefault();
230 event.preventDefault();
207 return false;
231 return false;
208 }
232 }
209 },
233 },
210
234
211 handleFocusOut: function(e) {
235 handleFocusOut: function(e) {
212 // Prevent a blur from firing if the blur was not user intended.
236 // Prevent a blur from firing if the blur was not user intended.
213 // This is a workaround for the return-key focus loss bug.
237 // This is a workaround for the return-key focus loss bug.
214 if (e.relatedTarget === null) {
238 if (e.relatedTarget === null) {
215 event.stopPropagation();
239 event.stopPropagation();
216 event.preventDefault();
240 event.preventDefault();
217 return false;
241 return false;
218 }
242 }
219 },
243 },
220 });
244 });
221 WidgetManager.register_widget_view('TextView', TextView);
245 WidgetManager.register_widget_view('TextView', TextView);
222 });
246 });
@@ -1,45 +1,53
1 // Test widget string class
1 // Test widget string class
2 casper.notebook_test(function () {
2 casper.notebook_test(function () {
3 index = this.append_cell(
3 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 'print("Success")');
6 'print("Success")');
7 this.execute_cell_then(index);
7 this.execute_cell_then(index);
8
8
9 var string_index = this.append_cell(
9 var string_index = this.append_cell(
10 'string_widget = [widgets.TextWidget(value = "xyz"),\n' +
10 'string_widget = [widgets.TextWidget(value = "xyz", placeholder = "abc"),\n' +
11 ' widgets.TextareaWidget(value = "xyz"),\n' +
11 ' widgets.TextareaWidget(value = "xyz", placeholder = "def"),\n' +
12 ' widgets.HTMLWidget(value = "xyz"),\n' +
12 ' widgets.HTMLWidget(value = "xyz"),\n' +
13 ' widgets.LatexWidget(value = "$\\\\LaTeX{}$")]\n' +
13 ' widgets.LatexWidget(value = "$\\\\LaTeX{}$")]\n' +
14 '[display(widget) for widget in string_widget]\n'+
14 '[display(widget) for widget in string_widget]\n'+
15 'print("Success")');
15 'print("Success")');
16 this.execute_cell_then(string_index, function(index){
16 this.execute_cell_then(string_index, function(index){
17
17
18 this.test.assertEquals(this.get_output_cell(index).text, 'Success\n',
18 this.test.assertEquals(this.get_output_cell(index).text, 'Success\n',
19 'Create string widget cell executed with correct output.');
19 'Create string widget cell executed with correct output.');
20
20
21 this.test.assert(this.cell_element_exists(index,
21 this.test.assert(this.cell_element_exists(index,
22 '.widget-area .widget-subarea'),
22 '.widget-area .widget-subarea'),
23 'Widget subarea exists.');
23 'Widget subarea exists.');
24
24
25 this.test.assert(this.cell_element_exists(index,
25 this.test.assert(this.cell_element_exists(index,
26 '.widget-area .widget-subarea .widget-hbox-single input[type=text]'),
26 '.widget-area .widget-subarea .widget-hbox-single input[type=text]'),
27 'Textbox exists.');
27 'Textbox exists.');
28
28
29 this.test.assert(this.cell_element_exists(index,
29 this.test.assert(this.cell_element_exists(index,
30 '.widget-area .widget-subarea .widget-hbox textarea'),
30 '.widget-area .widget-subarea .widget-hbox textarea'),
31 'Textarea exists.');
31 'Textarea exists.');
32
32
33 this.test.assert(this.cell_element_function(index,
33 this.test.assert(this.cell_element_function(index,
34 '.widget-area .widget-subarea .widget-hbox textarea', 'val')=='xyz',
34 '.widget-area .widget-subarea .widget-hbox textarea', 'val')=='xyz',
35 'Python set textarea value.');
35 'Python set textarea value.');
36
36
37 this.test.assert(this.cell_element_function(index,
37 this.test.assert(this.cell_element_function(index,
38 '.widget-area .widget-subarea .widget-hbox-single input[type=text]', 'val')=='xyz',
38 '.widget-area .widget-subarea .widget-hbox-single input[type=text]', 'val')=='xyz',
39 'Python set textbox value.');
39 'Python set textbox value.');
40
40
41 this.test.assert(this.cell_element_exists(string_index,
41 this.test.assert(this.cell_element_exists(string_index,
42 '.widget-area .widget-subarea div span.MathJax_Preview'),
42 '.widget-area .widget-subarea div span.MathJax_Preview'),
43 'MathJax parsed the LaTeX successfully.');
43 'MathJax parsed the LaTeX successfully.');
44
45 this.test.assert(this.cell_element_function(index,
46 '.widget-area .widget-subarea .widget-hbox textarea', 'attr', ['placeholder'])=='def',
47 'Python set textarea placeholder.');
48
49 this.test.assert(this.cell_element_function(index,
50 '.widget-area .widget-subarea .widget-hbox-single input[type=text]', 'attr', ['placeholder'])=='abc',
51 'Python set textbox placehoder.');
44 });
52 });
45 }); No newline at end of file
53 });
@@ -1,72 +1,73
1 """StringWidget class.
1 """StringWidget class.
2
2
3 Represents a unicode string using a widget.
3 Represents a unicode string 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, CallbackDispatcher
16 from .widget import DOMWidget, CallbackDispatcher
17 from IPython.utils.traitlets import Unicode, Bool
17 from IPython.utils.traitlets import Unicode, Bool
18
18
19 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
20 # Classes
20 # Classes
21 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
22 class _StringWidget(DOMWidget):
22 class _StringWidget(DOMWidget):
23 value = Unicode(help="String value", sync=True)
23 value = Unicode(help="String value", sync=True)
24 disabled = Bool(False, help="Enable or disable user changes", sync=True)
24 disabled = Bool(False, help="Enable or disable user changes", sync=True)
25 description = Unicode(help="Description of the value this widget represents", sync=True)
25 description = Unicode(help="Description of the value this widget represents", sync=True)
26 placeholder = Unicode("", help="Placeholder text to display when nothing has been typed", sync=True)
26
27
27
28
28 class HTMLWidget(_StringWidget):
29 class HTMLWidget(_StringWidget):
29 _view_name = Unicode('HTMLView', sync=True)
30 _view_name = Unicode('HTMLView', sync=True)
30
31
31
32
32 class LatexWidget(_StringWidget):
33 class LatexWidget(_StringWidget):
33 _view_name = Unicode('LatexView', sync=True)
34 _view_name = Unicode('LatexView', sync=True)
34
35
35
36
36 class TextareaWidget(_StringWidget):
37 class TextareaWidget(_StringWidget):
37 _view_name = Unicode('TextareaView', sync=True)
38 _view_name = Unicode('TextareaView', sync=True)
38
39
39 def scroll_to_bottom(self):
40 def scroll_to_bottom(self):
40 self.send({"method": "scroll_to_bottom"})
41 self.send({"method": "scroll_to_bottom"})
41
42
42
43
43 class TextWidget(_StringWidget):
44 class TextWidget(_StringWidget):
44 _view_name = Unicode('TextView', sync=True)
45 _view_name = Unicode('TextView', sync=True)
45
46
46 def __init__(self, **kwargs):
47 def __init__(self, **kwargs):
47 super(TextWidget, self).__init__(**kwargs)
48 super(TextWidget, self).__init__(**kwargs)
48 self._submission_callbacks = CallbackDispatcher()
49 self._submission_callbacks = CallbackDispatcher()
49 self.on_msg(self._handle_string_msg)
50 self.on_msg(self._handle_string_msg)
50
51
51 def _handle_string_msg(self, _, content):
52 def _handle_string_msg(self, _, content):
52 """Handle a msg from the front-end.
53 """Handle a msg from the front-end.
53
54
54 Parameters
55 Parameters
55 ----------
56 ----------
56 content: dict
57 content: dict
57 Content of the msg."""
58 Content of the msg."""
58 if content.get('event', '') == 'submit':
59 if content.get('event', '') == 'submit':
59 self._submission_callbacks(self)
60 self._submission_callbacks(self)
60
61
61 def on_submit(self, callback, remove=False):
62 def on_submit(self, callback, remove=False):
62 """(Un)Register a callback to handle text submission.
63 """(Un)Register a callback to handle text submission.
63
64
64 Triggered when the user clicks enter.
65 Triggered when the user clicks enter.
65
66
66 Parameters
67 Parameters
67 ----------
68 ----------
68 callback: callable
69 callback: callable
69 Will be called with exactly one argument: the Widget instance
70 Will be called with exactly one argument: the Widget instance
70 remove: bool (optional)
71 remove: bool (optional)
71 Whether to unregister the callback"""
72 Whether to unregister the callback"""
72 self._submission_callbacks.register_callback(callback, remove=remove)
73 self._submission_callbacks.register_callback(callback, remove=remove)
@@ -1,306 +1,339
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "cell_tags": [
3 "cell_tags": [
4 [
4 [
5 "<None>",
5 "<None>",
6 null
6 null
7 ]
7 ]
8 ],
8 ],
9 "name": "",
9 "name": "",
10 "signature": "sha256:9a70b52f0b16861d1cd6a8342b233247958977a52bde8d3efd69d21131ce1926"
10 "signature": "sha256:5ac3a85c8bb2f9bb3cd63b524bbb626ab1531176b43a109d13f5d7794f805eee"
11 },
11 },
12 "nbformat": 3,
12 "nbformat": 3,
13 "nbformat_minor": 0,
13 "nbformat_minor": 0,
14 "worksheets": [
14 "worksheets": [
15 {
15 {
16 "cells": [
16 "cells": [
17 {
17 {
18 "cell_type": "markdown",
18 "cell_type": "markdown",
19 "metadata": {},
19 "metadata": {},
20 "source": [
20 "source": [
21 "To use IPython widgets in the notebook, the widget namespace needs to be imported."
21 "To use IPython widgets in the notebook, the widget namespace needs to be imported."
22 ]
22 ]
23 },
23 },
24 {
24 {
25 "cell_type": "code",
25 "cell_type": "code",
26 "collapsed": false,
26 "collapsed": false,
27 "input": [
27 "input": [
28 "from IPython.html import widgets # Widget definitions\n",
28 "from IPython.html import widgets # Widget definitions\n",
29 "from IPython.display import display # Used to display widgets in the notebook"
29 "from IPython.display import display # Used to display widgets in the notebook"
30 ],
30 ],
31 "language": "python",
31 "language": "python",
32 "metadata": {},
32 "metadata": {},
33 "outputs": [],
33 "outputs": [],
34 "prompt_number": 1
34 "prompt_number": 2
35 },
35 },
36 {
36 {
37 "cell_type": "heading",
37 "cell_type": "heading",
38 "level": 1,
38 "level": 1,
39 "metadata": {},
39 "metadata": {},
40 "source": [
40 "source": [
41 "Basic Widgets"
41 "Basic Widgets"
42 ]
42 ]
43 },
43 },
44 {
44 {
45 "cell_type": "markdown",
45 "cell_type": "markdown",
46 "metadata": {},
46 "metadata": {},
47 "source": [
47 "source": [
48 "IPython comes with basic widgets that represent common interactive controls. These widgets are\n",
48 "IPython comes with basic widgets that represent common interactive controls. These widgets are\n",
49 "\n",
49 "\n",
50 "- CheckboxWidget\n",
50 "- CheckboxWidget\n",
51 "- ToggleButtonWidget\n",
51 "- ToggleButtonWidget\n",
52 "- FloatSliderWidget\n",
52 "- FloatSliderWidget\n",
53 "- BoundedFloatTextWidget\n",
53 "- BoundedFloatTextWidget\n",
54 "- FloatProgressWidget\n",
54 "- FloatProgressWidget\n",
55 "- FloatTextWidget\n",
55 "- FloatTextWidget\n",
56 "- ImageWidget\n",
56 "- ImageWidget\n",
57 "- IntSliderWidget\n",
57 "- IntSliderWidget\n",
58 "- BoundedIntTextWidget\n",
58 "- BoundedIntTextWidget\n",
59 "- IntProgressWidget\n",
59 "- IntProgressWidget\n",
60 "- IntTextWidget\n",
60 "- IntTextWidget\n",
61 "- ToggleButtonsWidget\n",
61 "- ToggleButtonsWidget\n",
62 "- RadioButtonsWidget\n",
62 "- RadioButtonsWidget\n",
63 "- DropdownWidget\n",
63 "- DropdownWidget\n",
64 "- SelectWidget\n",
64 "- SelectWidget\n",
65 "- HTMLWidget\n",
65 "- HTMLWidget\n",
66 "- LatexWidget\n",
66 "- LatexWidget\n",
67 "- TextareaWidget\n",
67 "- TextareaWidget\n",
68 "- TextWidget\n",
68 "- TextWidget\n",
69 "- ButtonWidget\n",
69 "- ButtonWidget\n",
70 "\n",
70 "\n",
71 "A few special widgets are also included, that can be used to capture events and change how other widgets are displayed. These widgets are\n",
71 "A few special widgets are also included, that can be used to capture events and change how other widgets are displayed. These widgets are\n",
72 "\n",
72 "\n",
73 "- ContainerWidget\n",
73 "- ContainerWidget\n",
74 "- PopupWidget\n",
74 "- PopupWidget\n",
75 "- AccordionWidget\n",
75 "- AccordionWidget\n",
76 "- TabWidget\n",
76 "- TabWidget\n",
77 "\n",
77 "\n",
78 "To see the complete list of widgets, one can execute the following"
78 "To see the complete list of widgets, one can execute the following"
79 ]
79 ]
80 },
80 },
81 {
81 {
82 "cell_type": "code",
82 "cell_type": "code",
83 "collapsed": false,
83 "collapsed": false,
84 "input": [
84 "input": [
85 "[widget for widget in dir(widgets) if widget.endswith('Widget')]"
85 "[widget for widget in dir(widgets) if widget.endswith('Widget')]"
86 ],
86 ],
87 "language": "python",
87 "language": "python",
88 "metadata": {},
88 "metadata": {},
89 "outputs": [
89 "outputs": [
90 {
90 {
91 "metadata": {},
91 "metadata": {},
92 "output_type": "pyout",
92 "output_type": "pyout",
93 "prompt_number": 2,
93 "prompt_number": 2,
94 "text": [
94 "text": [
95 "['AccordionWidget',\n",
95 "['AccordionWidget',\n",
96 " 'BoundedFloatTextWidget',\n",
96 " 'BoundedFloatTextWidget',\n",
97 " 'BoundedIntTextWidget',\n",
97 " 'BoundedIntTextWidget',\n",
98 " 'ButtonWidget',\n",
98 " 'ButtonWidget',\n",
99 " 'CheckboxWidget',\n",
99 " 'CheckboxWidget',\n",
100 " 'ContainerWidget',\n",
100 " 'ContainerWidget',\n",
101 " 'DOMWidget',\n",
101 " 'DOMWidget',\n",
102 " 'DropdownWidget',\n",
102 " 'DropdownWidget',\n",
103 " 'FloatProgressWidget',\n",
103 " 'FloatProgressWidget',\n",
104 " 'FloatSliderWidget',\n",
104 " 'FloatSliderWidget',\n",
105 " 'FloatTextWidget',\n",
105 " 'FloatTextWidget',\n",
106 " 'HTMLWidget',\n",
106 " 'HTMLWidget',\n",
107 " 'ImageWidget',\n",
107 " 'ImageWidget',\n",
108 " 'IntProgressWidget',\n",
108 " 'IntProgressWidget',\n",
109 " 'IntSliderWidget',\n",
109 " 'IntSliderWidget',\n",
110 " 'IntTextWidget',\n",
110 " 'IntTextWidget',\n",
111 " 'LatexWidget',\n",
111 " 'LatexWidget',\n",
112 " 'PopupWidget',\n",
112 " 'PopupWidget',\n",
113 " 'RadioButtonsWidget',\n",
113 " 'RadioButtonsWidget',\n",
114 " 'SelectWidget',\n",
114 " 'SelectWidget',\n",
115 " 'TabWidget',\n",
115 " 'TabWidget',\n",
116 " 'TextWidget',\n",
116 " 'TextWidget',\n",
117 " 'TextareaWidget',\n",
117 " 'TextareaWidget',\n",
118 " 'ToggleButtonWidget',\n",
118 " 'ToggleButtonWidget',\n",
119 " 'ToggleButtonsWidget',\n",
119 " 'ToggleButtonsWidget',\n",
120 " 'Widget']"
120 " 'Widget']"
121 ]
121 ]
122 }
122 }
123 ],
123 ],
124 "prompt_number": 2
124 "prompt_number": 2
125 },
125 },
126 {
126 {
127 "cell_type": "markdown",
127 "cell_type": "markdown",
128 "metadata": {},
128 "metadata": {},
129 "source": [
129 "source": [
130 "The basic widgets all have sensible default values. Create a *FloatSliderWidget* without displaying it:"
130 "The basic widgets all have sensible default values. Create a *FloatSliderWidget* without displaying it:"
131 ]
131 ]
132 },
132 },
133 {
133 {
134 "cell_type": "code",
134 "cell_type": "code",
135 "collapsed": false,
135 "collapsed": false,
136 "input": [
136 "input": [
137 "mywidget = widgets.FloatSliderWidget()"
137 "mywidget = widgets.FloatSliderWidget()"
138 ],
138 ],
139 "language": "python",
139 "language": "python",
140 "metadata": {},
140 "metadata": {},
141 "outputs": [],
141 "outputs": [],
142 "prompt_number": 3
142 "prompt_number": 3
143 },
143 },
144 {
144 {
145 "cell_type": "markdown",
145 "cell_type": "markdown",
146 "metadata": {},
146 "metadata": {},
147 "source": [
147 "source": [
148 "Constructing a widget does not display it on the page. To display a widget, the widget must be passed to the IPython `display(object)` method or must be returned as the last item in the cell. `mywidget` is displayed by"
148 "Constructing a widget does not display it on the page. To display a widget, the widget must be passed to the IPython `display(object)` method or must be returned as the last item in the cell. `mywidget` is displayed by"
149 ]
149 ]
150 },
150 },
151 {
151 {
152 "cell_type": "code",
152 "cell_type": "code",
153 "collapsed": false,
153 "collapsed": false,
154 "input": [
154 "input": [
155 "display(mywidget)"
155 "display(mywidget)"
156 ],
156 ],
157 "language": "python",
157 "language": "python",
158 "metadata": {},
158 "metadata": {},
159 "outputs": [],
159 "outputs": [],
160 "prompt_number": 4
160 "prompt_number": 4
161 },
161 },
162 {
162 {
163 "cell_type": "markdown",
163 "cell_type": "markdown",
164 "metadata": {},
164 "metadata": {},
165 "source": [
165 "source": [
166 "or"
166 "or"
167 ]
167 ]
168 },
168 },
169 {
169 {
170 "cell_type": "code",
170 "cell_type": "code",
171 "collapsed": false,
171 "collapsed": false,
172 "input": [
172 "input": [
173 "mywidget"
173 "mywidget"
174 ],
174 ],
175 "language": "python",
175 "language": "python",
176 "metadata": {},
176 "metadata": {},
177 "outputs": [],
177 "outputs": [],
178 "prompt_number": 5
178 "prompt_number": 5
179 },
179 },
180 {
180 {
181 "cell_type": "markdown",
181 "cell_type": "markdown",
182 "metadata": {},
182 "metadata": {},
183 "source": [
183 "source": [
184 "It's important to realize that widgets are not the same as output, even though they are displayed with `display`. Widgets are drawn in a special widget area. That area is marked with a close button which allows you to collapse the widgets. Widgets cannot be interleaved with output. Doing so would break the ability to make simple animations using `clear_output`.\n",
184 "It's important to realize that widgets are not the same as output, even though they are displayed with `display`. Widgets are drawn in a special widget area. That area is marked with a close button which allows you to collapse the widgets. Widgets cannot be interleaved with output. Doing so would break the ability to make simple animations using `clear_output`.\n",
185 "\n",
185 "\n",
186 "Widgets are manipulated via special instance attributes (traitlets). The names of these traitlets are listed in the widget's `keys` attribute (as seen below). A few of these attributes are common to most widgets. The basic attributes are `value`, `description`, `visible`, and `disabled`. `_css` and `_view_name` are private attributes that exist in all widgets and should not be modified."
186 "Widgets are manipulated via special instance attributes (traitlets). The names of these traitlets are listed in the widget's `keys` attribute (as seen below). A few of these attributes are common to most widgets. The basic attributes are `value`, `description`, `visible`, and `disabled`. `_css` and `_view_name` are private attributes that exist in all widgets and should not be modified."
187 ]
187 ]
188 },
188 },
189 {
189 {
190 "cell_type": "code",
190 "cell_type": "code",
191 "collapsed": false,
191 "collapsed": false,
192 "input": [
192 "input": [
193 "mywidget.keys"
193 "mywidget.keys"
194 ],
194 ],
195 "language": "python",
195 "language": "python",
196 "metadata": {},
196 "metadata": {},
197 "outputs": [
197 "outputs": [
198 {
198 {
199 "metadata": {},
199 "metadata": {},
200 "output_type": "pyout",
200 "output_type": "pyout",
201 "prompt_number": 6,
201 "prompt_number": 6,
202 "text": [
202 "text": [
203 "['_view_name',\n",
203 "['_view_name',\n",
204 " 'orientation',\n",
204 " 'orientation',\n",
205 " 'min',\n",
205 " 'min',\n",
206 " 'max',\n",
206 " 'max',\n",
207 " '_css',\n",
207 " '_css',\n",
208 " 'value',\n",
208 " 'value',\n",
209 " 'disabled',\n",
209 " 'disabled',\n",
210 " 'visible',\n",
210 " 'visible',\n",
211 " 'step',\n",
211 " 'step',\n",
212 " 'description']"
212 " 'description']"
213 ]
213 ]
214 }
214 }
215 ],
215 ],
216 "prompt_number": 6
216 "prompt_number": 6
217 },
217 },
218 {
218 {
219 "cell_type": "markdown",
219 "cell_type": "markdown",
220 "metadata": {},
220 "metadata": {},
221 "source": [
221 "source": [
222 "Changing a widget's attribute will automatically update that widget everywhere it is displayed in the notebook. Here, the `value` attribute of `mywidget` is set. The slider shown above updates automatically with the new value. Syncing also works in the other direction - changing the value of the displayed widget will update the property's value."
222 "Changing a widget's attribute will automatically update that widget everywhere it is displayed in the notebook. Here, the `value` attribute of `mywidget` is set. The slider shown above updates automatically with the new value. Syncing also works in the other direction - changing the value of the displayed widget will update the property's value."
223 ]
223 ]
224 },
224 },
225 {
225 {
226 "cell_type": "code",
226 "cell_type": "code",
227 "collapsed": false,
227 "collapsed": false,
228 "input": [
228 "input": [
229 "mywidget.value = 25.0"
229 "mywidget.value = 25.0"
230 ],
230 ],
231 "language": "python",
231 "language": "python",
232 "metadata": {},
232 "metadata": {},
233 "outputs": [],
233 "outputs": [],
234 "prompt_number": 7
234 "prompt_number": 7
235 },
235 },
236 {
236 {
237 "cell_type": "markdown",
237 "cell_type": "markdown",
238 "metadata": {},
238 "metadata": {},
239 "source": [
239 "source": [
240 "After changing the widget's value in the notebook by hand to 0.0 (sliding the bar to the far left)."
240 "After changing the widget's value in the notebook by hand to 0.0 (sliding the bar to the far left)."
241 ]
241 ]
242 },
242 },
243 {
243 {
244 "cell_type": "code",
244 "cell_type": "code",
245 "collapsed": false,
245 "collapsed": false,
246 "input": [
246 "input": [
247 "mywidget.value"
247 "mywidget.value"
248 ],
248 ],
249 "language": "python",
249 "language": "python",
250 "metadata": {},
250 "metadata": {},
251 "outputs": [
251 "outputs": [
252 {
252 {
253 "metadata": {},
253 "metadata": {},
254 "output_type": "pyout",
254 "output_type": "pyout",
255 "prompt_number": 8,
255 "prompt_number": 8,
256 "text": [
256 "text": [
257 "25.0"
257 "25.0"
258 ]
258 ]
259 }
259 }
260 ],
260 ],
261 "prompt_number": 8
261 "prompt_number": 8
262 },
262 },
263 {
263 {
264 "cell_type": "markdown",
264 "cell_type": "markdown",
265 "metadata": {},
265 "metadata": {},
266 "source": [
266 "source": [
267 "Widget values can also be set with kwargs during the construction of the widget (as seen below)."
267 "Widget values can also be set with kwargs during the construction of the widget (as seen below)."
268 ]
268 ]
269 },
269 },
270 {
270 {
271 "cell_type": "code",
271 "cell_type": "code",
272 "collapsed": false,
272 "collapsed": false,
273 "input": [
273 "input": [
274 "mysecondwidget = widgets.RadioButtonsWidget(values=[\"Item A\", \"Item B\", \"Item C\"], value=\"Item A\")\n",
274 "mysecondwidget = widgets.RadioButtonsWidget(values=[\"Item A\", \"Item B\", \"Item C\"], value=\"Item A\")\n",
275 "display(mysecondwidget)"
275 "display(mysecondwidget)"
276 ],
276 ],
277 "language": "python",
277 "language": "python",
278 "metadata": {},
278 "metadata": {},
279 "outputs": [],
279 "outputs": [],
280 "prompt_number": 9
280 "prompt_number": 9
281 },
281 },
282 {
282 {
283 "cell_type": "code",
283 "cell_type": "code",
284 "collapsed": false,
284 "collapsed": false,
285 "input": [
285 "input": [
286 "mysecondwidget.value"
286 "mysecondwidget.value"
287 ],
287 ],
288 "language": "python",
288 "language": "python",
289 "metadata": {},
289 "metadata": {},
290 "outputs": [
290 "outputs": [
291 {
291 {
292 "metadata": {},
292 "metadata": {},
293 "output_type": "pyout",
293 "output_type": "pyout",
294 "prompt_number": 10,
294 "prompt_number": 10,
295 "text": [
295 "text": [
296 "'Item A'"
296 "'Item A'"
297 ]
297 ]
298 }
298 }
299 ],
299 ],
300 "prompt_number": 10
300 "prompt_number": 10
301 },
302 {
303 "cell_type": "markdown",
304 "metadata": {},
305 "source": [
306 "Some widgets have special attributes. For example, text boxes and text areas can specify the `placeholder` attribute, which will set \"placeholder\" text to be displayed before the user has typed anything:"
307 ]
308 },
309 {
310 "cell_type": "code",
311 "collapsed": false,
312 "input": [
313 "mytextwidget = widgets.TextWidget()\n",
314 "mytextwidget.placeholder = \"type something here\"\n",
315 "display(mytextwidget)"
316 ],
317 "language": "python",
318 "metadata": {},
319 "outputs": [],
320 "prompt_number": 4
321 },
322 {
323 "cell_type": "code",
324 "collapsed": false,
325 "input": [
326 "mytextareawidget = widgets.TextareaWidget()\n",
327 "mytextareawidget.placeholder = \"your text here\"\n",
328 "display(mytextareawidget)"
329 ],
330 "language": "python",
331 "metadata": {},
332 "outputs": [],
333 "prompt_number": 5
301 }
334 }
302 ],
335 ],
303 "metadata": {}
336 "metadata": {}
304 }
337 }
305 ]
338 ]
306 } No newline at end of file
339 }
General Comments 0
You need to be logged in to leave comments. Login now