##// END OF EJS Templates
Updated examples 3-6
Jonathan Frederic -
Show More
@@ -46,133 +46,38 b''
46 "cell_type": "code",
46 "cell_type": "code",
47 "collapsed": false,
47 "collapsed": false,
48 "input": [
48 "input": [
49 "floatrange = widgets.FloatSliderWidget() # You can set the parent in the constructor,\n",
49 "floatrange = widgets.FloatSliderWidget()\n",
50 "\n",
50 "string = widgets.TextBoxWidget(value='hi')\n",
51 "string = widgets.TextBocWidget(value='hi')\n",
52 "container = widgets.ContainerWidget(children=[floatrange, string])\n",
51 "container = widgets.ContainerWidget(children=[floatrange, string])\n",
53 "\n",
52 "\n",
54 "display(container) # Displays the `container` and all of it's children."
53 "display(container) # Displays the `container` and all of it's children."
55 ],
54 ],
56 "language": "python",
55 "language": "python",
57 "metadata": {},
56 "metadata": {},
58 "outputs": [
59 {
60 "ename": "AttributeError",
61 "evalue": "'module' object has no attribute 'TextBocWidget'",
62 "output_type": "pyerr",
63 "traceback": [
64 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
65 "\u001b[1;32m<ipython-input-4-085d43fdae3d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mfloatrange\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwidgets\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mFloatSliderWidget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# You can set the parent in the constructor,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mstring\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwidgets\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mTextBocWidget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'hi'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[0mcontainer\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mwidgets\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mContainerWidget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mchildren\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mfloatrange\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstring\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
66 "\u001b[1;31mAttributeError\u001b[0m: 'module' object has no attribute 'TextBocWidget'"
67 ]
68 }
69 ],
70 "prompt_number": 4
71 },
72 {
73 "cell_type": "markdown",
74 "metadata": {},
75 "source": [
76 "Children can also be added to parents after the parent has been displayed. If the children are added after the parent has already been displayed, the children must be displayed themselves.\n",
77 "\n",
78 "In the example below, the IntRangeWidget is never rendered since display was called on the parent before the parent/child relationship was established."
79 ]
80 },
81 {
82 "cell_type": "code",
83 "collapsed": false,
84 "input": [
85 "intrange = widgets.IntRangeWidget() # Never gets displayed.\n",
86 "container = widgets.MulticontainerWidget(children=[intrange])\n",
87 "\n",
88 "display(container)\n"
89 ],
90 "language": "python",
91 "metadata": {},
92 "outputs": [],
93 "prompt_number": 5
94 },
95 {
96 "cell_type": "markdown",
97 "metadata": {},
98 "source": [
99 "Calling display on the child fixes the problem."
100 ]
101 },
102 {
103 "cell_type": "code",
104 "collapsed": false,
105 "input": [
106 "container = widgets.MulticontainerWidget()\n",
107 "display(container)\n",
108 "\n",
109 "intrange = widgets.IntRangeWidget(parent=container)\n",
110 "display(intrange) # This line is needed since the `container` has already been displayed."
111 ],
112 "language": "python",
113 "metadata": {},
114 "outputs": [],
115 "prompt_number": 4
116 },
117 {
118 "cell_type": "heading",
119 "level": 1,
120 "metadata": {},
121 "source": [
122 "Changing Child Views"
123 ]
124 },
125 {
126 "cell_type": "markdown",
127 "metadata": {},
128 "source": [
129 "The view used to display a widget must defined by the time the widget is displayed. If children widgets are to be displayed along with the parent in one call, their `view_name`s can't be set since all of the widgets are sharing the same display call. Instead, their `default_view_name`s must be set (as seen below)."
130 ]
131 },
132 {
133 "cell_type": "code",
134 "collapsed": false,
135 "input": [
136 "\n",
137 "floatrange = widgets.FloatRangeWidget()\n",
138 "floatrange.default_view_name = \"FloatTextView\" # It can be set as a property.\n",
139 "\n",
140 "string = widgets.StringWidget(default_view_name = \"TextAreaView\") # It can also be set in the constructor.\n",
141 "container = widgets.MulticontainerWidget(children=[floatrange, string])\n",
142 "display(container)"
143 ],
144 "language": "python",
145 "metadata": {},
146 "outputs": [],
57 "outputs": [],
147 "prompt_number": 6
58 "prompt_number": 2
148 },
59 },
149 {
60 {
150 "cell_type": "markdown",
61 "cell_type": "markdown",
151 "metadata": {},
62 "metadata": {},
152 "source": [
63 "source": [
153 "However, if the children are displayed after the parent, their `view_name` can also be set like normal. Both methods will work. The code below produces the same output as the code above."
64 "Children can also be added to parents after the parent has been displayed. The parent is responsible for rendering its children."
154 ]
65 ]
155 },
66 },
156 {
67 {
157 "cell_type": "code",
68 "cell_type": "code",
158 "collapsed": false,
69 "collapsed": false,
159 "input": [
70 "input": [
160 "container = widgets.MulticontainerWidget()\n",
71 "container = widgets.ContainerWidget()\n",
161 "display(container)\n",
72 "display(container)\n",
162 "\n",
73 "\n",
163 "floatrange = widgets.FloatRangeWidget()\n",
74 "intrange = widgets.IntSliderWidget()\n",
164 "floatrange.parent=container\n",
75 "container.children=[intrange]\n"
165 "display(floatrange, view_name = \"FloatTextView\") # view_name can be set during display.\n",
166 "\n",
167 "string = widgets.StringWidget()\n",
168 "string.parent = container\n",
169 "string.default_view_name = \"TextAreaView\" # Setting default_view_name still works.\n",
170 "display(string)\n"
171 ],
76 ],
172 "language": "python",
77 "language": "python",
173 "metadata": {},
78 "metadata": {},
174 "outputs": [],
79 "outputs": [],
175 "prompt_number": 6
80 "prompt_number": 3
176 },
81 },
177 {
82 {
178 "cell_type": "heading",
83 "cell_type": "heading",
@@ -186,20 +91,20 b''
186 "cell_type": "markdown",
91 "cell_type": "markdown",
187 "metadata": {},
92 "metadata": {},
188 "source": [
93 "source": [
189 "Sometimes it's necessary to hide/show widget views in place, without ruining the order that they have been displayed on the page. Using the `display` method, the views are always added to the end of their respective containers. Instead the `visibility` property of widgets can be used to hide/show widgets that have already been displayed (as seen below)."
94 "Sometimes it's necessary to hide/show widget views in place, without having to redisplay the widget views. The `visibility` property of widgets can be used to hide/show widgets that have already been displayed (as seen below)."
190 ]
95 ]
191 },
96 },
192 {
97 {
193 "cell_type": "code",
98 "cell_type": "code",
194 "collapsed": false,
99 "collapsed": false,
195 "input": [
100 "input": [
196 "string = widgets.StringWidget(value=\"Hello World!\")\n",
101 "string = widgets.LatexWidget(value=\"Hello World!\")\n",
197 "display(string, view_name=\"HTMLView\") "
102 "display(string) "
198 ],
103 ],
199 "language": "python",
104 "language": "python",
200 "metadata": {},
105 "metadata": {},
201 "outputs": [],
106 "outputs": [],
202 "prompt_number": 7
107 "prompt_number": 4
203 },
108 },
204 {
109 {
205 "cell_type": "code",
110 "cell_type": "code",
@@ -210,7 +115,7 b''
210 "language": "python",
115 "language": "python",
211 "metadata": {},
116 "metadata": {},
212 "outputs": [],
117 "outputs": [],
213 "prompt_number": 8
118 "prompt_number": 5
214 },
119 },
215 {
120 {
216 "cell_type": "code",
121 "cell_type": "code",
@@ -221,7 +126,7 b''
221 "language": "python",
126 "language": "python",
222 "metadata": {},
127 "metadata": {},
223 "outputs": [],
128 "outputs": [],
224 "prompt_number": 9
129 "prompt_number": 6
225 },
130 },
226 {
131 {
227 "cell_type": "markdown",
132 "cell_type": "markdown",
@@ -235,38 +140,20 b''
235 "collapsed": false,
140 "collapsed": false,
236 "input": [
141 "input": [
237 "form = widgets.ContainerWidget()\n",
142 "form = widgets.ContainerWidget()\n",
238 "first = widgets.StringWidget(description=\"First Name:\")\n",
143 "first = widgets.TextBoxWidget(description=\"First Name:\")\n",
239 "last = widgets.StringWidget(description=\"Last Name:\")\n",
144 "last = widgets.TextBoxWidget(description=\"Last Name:\")\n",
240 "\n",
145 "\n",
241 "student = widgets.BoolWidget(description=\"Student:\", value=False)\n",
146 "student = widgets.CheckBoxWidget(description=\"Student:\", value=False)\n",
242 "form.children=[first, last, student]\n",
243 "display(form)"
244 ],
245 "language": "python",
246 "metadata": {},
247 "outputs": [],
248 "prompt_number": 2
249 },
250 {
251 "cell_type": "code",
252 "collapsed": false,
253 "input": [
254 "form = widgets.ContainerWidget()\n",
255 "first = widgets.StringWidget(description=\"First Name:\")\n",
256 "last = widgets.StringWidget(description=\"Last Name:\")\n",
257 "\n",
258 "student = widgets.BoolWidget(description=\"Student:\", value=False)\n",
259 "school_info = widgets.ContainerWidget(visible=False, children=[\n",
147 "school_info = widgets.ContainerWidget(visible=False, children=[\n",
260 " widgets.StringWidget(description=\"School:\"),\n",
148 " widgets.TextBoxWidget(description=\"School:\"),\n",
261 " widgets.IntRangeWidget(description=\"Grade:\", min=0, max=12, default_view_name='IntTextView')\n",
149 " widgets.IntTextWidget(description=\"Grade:\", min=0, max=12)\n",
262 " ])\n",
150 " ])\n",
263 "\n",
151 "\n",
264 "pet = widgets.StringWidget(description=\"Pet's Name:\")\n",
152 "pet = widgets.TextBoxWidget(description=\"Pet's Name:\")\n",
265 "form.children = [first, last, student, school_info, pet]\n",
153 "form.children = [first, last, student, school_info, pet]\n",
266 "display(form)\n",
154 "display(form)\n",
267 "\n",
155 "\n",
268 "def on_student_toggle(name, value):\n",
156 "def on_student_toggle(name, value):\n",
269 " print value\n",
270 " if value:\n",
157 " if value:\n",
271 " school_info.visible = True\n",
158 " school_info.visible = True\n",
272 " else:\n",
159 " else:\n",
@@ -275,59 +162,8 b''
275 ],
162 ],
276 "language": "python",
163 "language": "python",
277 "metadata": {},
164 "metadata": {},
278 "outputs": [
165 "outputs": [],
279 {
166 "prompt_number": 7
280 "output_type": "stream",
281 "stream": "stdout",
282 "text": [
283 "True\n"
284 ]
285 },
286 {
287 "output_type": "stream",
288 "stream": "stdout",
289 "text": [
290 "False\n"
291 ]
292 },
293 {
294 "output_type": "stream",
295 "stream": "stdout",
296 "text": [
297 "True\n"
298 ]
299 },
300 {
301 "output_type": "stream",
302 "stream": "stdout",
303 "text": [
304 "False\n"
305 ]
306 },
307 {
308 "output_type": "stream",
309 "stream": "stdout",
310 "text": [
311 "True\n"
312 ]
313 },
314 {
315 "output_type": "stream",
316 "stream": "stdout",
317 "text": [
318 "False\n"
319 ]
320 }
321 ],
322 "prompt_number": 2
323 },
324 {
325 "cell_type": "code",
326 "collapsed": false,
327 "input": [],
328 "language": "python",
329 "metadata": {},
330 "outputs": []
331 }
167 }
332 ],
168 ],
333 "metadata": {}
169 "metadata": {}
@@ -44,7 +44,7 b''
44 "cell_type": "code",
44 "cell_type": "code",
45 "collapsed": false,
45 "collapsed": false,
46 "input": [
46 "input": [
47 "print(widgets.Widget.set_css.__doc__)"
47 "print(widgets.DOMWidget.set_css.__doc__)"
48 ],
48 ],
49 "language": "python",
49 "language": "python",
50 "metadata": {},
50 "metadata": {},
@@ -53,10 +53,11 b''
53 "output_type": "stream",
53 "output_type": "stream",
54 "stream": "stdout",
54 "stream": "stdout",
55 "text": [
55 "text": [
56 "Set one or more CSS properties of the widget (shared among all of the\n",
56 "Set one or more CSS properties of the widget.\n",
57 " views). This function has two signatures:\n",
57 "\n",
58 " - set_css(css_dict, [selector=''])\n",
58 " This function has two signatures:\n",
59 " - set_css(key, value, [selector=''])\n",
59 " - set_css(css_dict, selector='')\n",
60 " - set_css(key, value, selector='')\n",
60 "\n",
61 "\n",
61 " Parameters\n",
62 " Parameters\n",
62 " ----------\n",
63 " ----------\n",
@@ -67,7 +68,12 b''
67 " value\n",
68 " value\n",
68 " CSS value\n",
69 " CSS value\n",
69 " selector: unicode (optional)\n",
70 " selector: unicode (optional)\n",
70 " JQuery selector to use to apply the CSS key/value.\n",
71 " JQuery selector to use to apply the CSS key/value. If no selector \n",
72 " is provided, an empty selector is used. An empty selector makes the \n",
73 " front-end try to apply the css to a default element. The default\n",
74 " element is an attribute unique to each view, which is a DOM element\n",
75 " of the view that should be styled with common CSS (see \n",
76 " `$el_to_style` in the Javascript code).\n",
71 " \n"
77 " \n"
72 ]
78 ]
73 }
79 }
@@ -85,7 +91,7 b''
85 "cell_type": "code",
91 "cell_type": "code",
86 "collapsed": false,
92 "collapsed": false,
87 "input": [
93 "input": [
88 "print(widgets.Widget.get_css.__doc__)"
94 "print(widgets.DOMWidget.get_css.__doc__)"
89 ],
95 ],
90 "language": "python",
96 "language": "python",
91 "metadata": {},
97 "metadata": {},
@@ -94,9 +100,10 b''
94 "output_type": "stream",
100 "output_type": "stream",
95 "stream": "stdout",
101 "stream": "stdout",
96 "text": [
102 "text": [
97 "Get a CSS property of the widget. Note, this function does not\n",
103 "Get a CSS property of the widget.\n",
98 " actually request the CSS from the front-end; Only properties that have\n",
104 "\n",
99 " been set with set_css can be read.\n",
105 " Note: This function does not actually request the CSS from the \n",
106 " front-end; Only properties that have been set with set_css can be read.\n",
100 "\n",
107 "\n",
101 " Parameters\n",
108 " Parameters\n",
102 " ----------\n",
109 " ----------\n",
@@ -121,8 +128,8 b''
121 "cell_type": "code",
128 "cell_type": "code",
122 "collapsed": false,
129 "collapsed": false,
123 "input": [
130 "input": [
124 "label = widgets.StringWidget(default_view_name=\"HTMLView\")\n",
131 "label = widgets.LatexWidget()\n",
125 "label.value = \"<strong>ALERT: </strong> Hello World!\"\n",
132 "label.value = \"$\\\\textbf{ALERT:} Hello World!$\"\n",
126 "container = widgets.ContainerWidget(children=[label])\n",
133 "container = widgets.ContainerWidget(children=[label])\n",
127 "\n",
134 "\n",
128 "# set_css used to set a single CSS attribute.\n",
135 "# set_css used to set a single CSS attribute.\n",
@@ -158,7 +165,7 b''
158 "cell_type": "code",
165 "cell_type": "code",
159 "collapsed": false,
166 "collapsed": false,
160 "input": [
167 "input": [
161 "print(widgets.Widget.add_class.__doc__)"
168 "print(widgets.DOMWidget.add_class.__doc__)"
162 ],
169 ],
163 "language": "python",
170 "language": "python",
164 "metadata": {},
171 "metadata": {},
@@ -167,13 +174,12 b''
167 "output_type": "stream",
174 "output_type": "stream",
168 "stream": "stdout",
175 "stream": "stdout",
169 "text": [
176 "text": [
170 "Add class[es] to a DOM element\n",
177 "Add class[es] to a DOM element.\n",
171 "\n",
178 "\n",
172 " Parameters\n",
179 " Parameters\n",
173 " ----------\n",
180 " ----------\n",
174 " class_name: unicode\n",
181 " class_names: unicode or list\n",
175 " Class name(s) to add to the DOM element(s). Multiple class names\n",
182 " Class name(s) to add to the DOM element(s).\n",
176 " must be space separated.\n",
177 " selector: unicode (optional)\n",
183 " selector: unicode (optional)\n",
178 " JQuery selector to select the DOM element(s) that the class(es) will\n",
184 " JQuery selector to select the DOM element(s) that the class(es) will\n",
179 " be added to.\n",
185 " be added to.\n",
@@ -199,8 +205,8 b''
199 " 'padding': '6px', \n",
205 " 'padding': '6px', \n",
200 " 'background': 'yellow'}) \n",
206 " 'background': 'yellow'}) \n",
201 "\n",
207 "\n",
202 "label = widgets.StringWidget(default_view_name=\"HTMLView\")\n",
208 "label = widgets.LatexWidget()\n",
203 "label.value = \"<strong>ALERT: </strong> Hello World!\"\n",
209 "label.value = \"$\\\\textbf{ALERT:} Hello World!$\"\n",
204 "container.children = [label]\n",
210 "container.children = [label]\n",
205 "display(container)\n",
211 "display(container)\n",
206 "container.add_class('corner-all') # Must be called AFTER display"
212 "container.add_class('corner-all') # Must be called AFTER display"
@@ -208,7 +214,7 b''
208 "language": "python",
214 "language": "python",
209 "metadata": {},
215 "metadata": {},
210 "outputs": [],
216 "outputs": [],
211 "prompt_number": 7
217 "prompt_number": 6
212 },
218 },
213 {
219 {
214 "cell_type": "markdown",
220 "cell_type": "markdown",
@@ -221,8 +227,8 b''
221 "cell_type": "code",
227 "cell_type": "code",
222 "collapsed": false,
228 "collapsed": false,
223 "input": [
229 "input": [
224 "label = widgets.StringWidget(value = \"<strong>ALERT: </strong> Hello World!\")\n",
230 "label = widgets.LatexWidget(value = \"$\\\\textbf{ALERT:} Hello World!$\")\n",
225 "display(label, view_name=\"HTMLView\")\n",
231 "display(label)\n",
226 "\n",
232 "\n",
227 "# Apply twitter bootstrap alert class to the label.\n",
233 "# Apply twitter bootstrap alert class to the label.\n",
228 "label.add_class(\"alert\")"
234 "label.add_class(\"alert\")"
@@ -230,7 +236,7 b''
230 "language": "python",
236 "language": "python",
231 "metadata": {},
237 "metadata": {},
232 "outputs": [],
238 "outputs": [],
233 "prompt_number": 11
239 "prompt_number": 7
234 },
240 },
235 {
241 {
236 "cell_type": "markdown",
242 "cell_type": "markdown",
@@ -260,7 +266,7 b''
260 "language": "python",
266 "language": "python",
261 "metadata": {},
267 "metadata": {},
262 "outputs": [],
268 "outputs": [],
263 "prompt_number": 12
269 "prompt_number": 8
264 },
270 },
265 {
271 {
266 "cell_type": "markdown",
272 "cell_type": "markdown",
@@ -273,7 +279,7 b''
273 "cell_type": "code",
279 "cell_type": "code",
274 "collapsed": false,
280 "collapsed": false,
275 "input": [
281 "input": [
276 "print(widgets.Widget.remove_class.__doc__)"
282 "print(widgets.DOMWidget.remove_class.__doc__)"
277 ],
283 ],
278 "language": "python",
284 "language": "python",
279 "metadata": {},
285 "metadata": {},
@@ -282,13 +288,12 b''
282 "output_type": "stream",
288 "output_type": "stream",
283 "stream": "stdout",
289 "stream": "stdout",
284 "text": [
290 "text": [
285 "Remove class[es] from a DOM element\n",
291 "Remove class[es] from a DOM element.\n",
286 "\n",
292 "\n",
287 " Parameters\n",
293 " Parameters\n",
288 " ----------\n",
294 " ----------\n",
289 " class_name: unicode\n",
295 " class_names: unicode or list\n",
290 " Class name(s) to remove from the DOM element(s). Multiple class\n",
296 " Class name(s) to remove from the DOM element(s).\n",
291 " names must be space separated.\n",
292 " selector: unicode (optional)\n",
297 " selector: unicode (optional)\n",
293 " JQuery selector to select the DOM element(s) that the class(es) will\n",
298 " JQuery selector to select the DOM element(s) that the class(es) will\n",
294 " be removed from.\n",
299 " be removed from.\n",
@@ -296,7 +301,7 b''
296 ]
301 ]
297 }
302 }
298 ],
303 ],
299 "prompt_number": 13
304 "prompt_number": 9
300 },
305 },
301 {
306 {
302 "cell_type": "markdown",
307 "cell_type": "markdown",
@@ -310,8 +315,8 b''
310 "collapsed": false,
315 "collapsed": false,
311 "input": [
316 "input": [
312 "import time\n",
317 "import time\n",
313 "label = widgets.StringWidget(value = \"<strong>ALERT: </strong> Hello World!\")\n",
318 "label = widgets.LatexWidget(value = \"$\\\\textbf{ALERT:} Hello World!$\")\n",
314 "display(label, view_name=\"HTMLView\")\n",
319 "display(label)\n",
315 "\n",
320 "\n",
316 "# Apply twitter bootstrap alert class to the label.\n",
321 "# Apply twitter bootstrap alert class to the label.\n",
317 "label.add_class(\"alert\")\n",
322 "label.add_class(\"alert\")\n",
@@ -327,15 +332,7 b''
327 "language": "python",
332 "language": "python",
328 "metadata": {},
333 "metadata": {},
329 "outputs": [],
334 "outputs": [],
330 "prompt_number": 14
335 "prompt_number": 10
331 },
332 {
333 "cell_type": "code",
334 "collapsed": false,
335 "input": [],
336 "language": "python",
337 "metadata": {},
338 "outputs": []
339 }
336 }
340 ],
337 ],
341 "metadata": {}
338 "metadata": {}
@@ -44,9 +44,9 b''
44 "cell_type": "code",
44 "cell_type": "code",
45 "collapsed": false,
45 "collapsed": false,
46 "input": [
46 "input": [
47 "display(widgets.StringWidget(description=\"a:\"))\n",
47 "display(widgets.TextBoxWidget(description=\"a:\"))\n",
48 "display(widgets.StringWidget(description=\"aa:\"))\n",
48 "display(widgets.TextBoxWidget(description=\"aa:\"))\n",
49 "display(widgets.StringWidget(description=\"aaa:\"))"
49 "display(widgets.TextBoxWidget(description=\"aaa:\"))"
50 ],
50 ],
51 "language": "python",
51 "language": "python",
52 "metadata": {},
52 "metadata": {},
@@ -64,10 +64,10 b''
64 "cell_type": "code",
64 "cell_type": "code",
65 "collapsed": false,
65 "collapsed": false,
66 "input": [
66 "input": [
67 "display(widgets.StringWidget(description=\"a:\"))\n",
67 "display(widgets.TextBoxWidget(description=\"a:\"))\n",
68 "display(widgets.StringWidget(description=\"aa:\"))\n",
68 "display(widgets.TextBoxWidget(description=\"aa:\"))\n",
69 "display(widgets.StringWidget(description=\"aaa:\"))\n",
69 "display(widgets.TextBoxWidget(description=\"aaa:\"))\n",
70 "display(widgets.StringWidget(description=\"aaaaaaaaaaaaaaaaaa:\"))"
70 "display(widgets.TextBoxWidget(description=\"aaaaaaaaaaaaaaaaaa:\"))"
71 ],
71 ],
72 "language": "python",
72 "language": "python",
73 "metadata": {},
73 "metadata": {},
@@ -85,10 +85,10 b''
85 "cell_type": "code",
85 "cell_type": "code",
86 "collapsed": false,
86 "collapsed": false,
87 "input": [
87 "input": [
88 "display(widgets.StringWidget(description=\"a:\"))\n",
88 "display(widgets.TextBoxWidget(description=\"a:\"))\n",
89 "display(widgets.StringWidget(description=\"aa:\"))\n",
89 "display(widgets.TextBoxWidget(description=\"aa:\"))\n",
90 "display(widgets.StringWidget(description=\"aaa:\"))\n",
90 "display(widgets.TextBoxWidget(description=\"aaa:\"))\n",
91 "display(widgets.StringWidget())"
91 "display(widgets.TextBoxWidget())"
92 ],
92 ],
93 "language": "python",
93 "language": "python",
94 "metadata": {},
94 "metadata": {},
@@ -123,7 +123,14 b''
123 "}\n",
123 "}\n",
124 "\n",
124 "\n",
125 "def make_container(title):\n",
125 "def make_container(title):\n",
126 " display(widgets.StringWidget(default_view_name='HTMLView', value='<h2><br>' + title + '</h2>'))\n",
126 " header = widgets.LatexWidget(value=title) \n",
127 " display(header)\n",
128 " header.set_css({\n",
129 " 'font-size': '30pt',\n",
130 " 'margin-top': '40pt',\n",
131 " 'margin-bottom': '20pt',\n",
132 " })\n",
133 " \n",
127 " container = widgets.ContainerWidget()\n",
134 " container = widgets.ContainerWidget()\n",
128 " container.set_css('background', '#999999')\n",
135 " container.set_css('background', '#999999')\n",
129 " display(container)\n",
136 " display(container)\n",
@@ -132,16 +139,16 b''
132 "def fill_container(container):\n",
139 "def fill_container(container):\n",
133 " components = []\n",
140 " components = []\n",
134 " for i in range(3):\n",
141 " for i in range(3):\n",
135 " components.append(widgets.StringWidget(default_view_name='HTMLView', value=\"ABC\"[i]))\n",
142 " components.append(widgets.LatexWidget(value=\"ABC\"[i]))\n",
136 " components[i].set_css(child_style)\n",
143 " components[i].set_css(child_style)\n",
137 " container.children = components\n",
144 " container.children = components\n",
138 " \n",
145 " \n",
139 "container = make_container('VBox')\n",
146 "container = make_container('VBox')\n",
140 "container.vbox()\n",
147 "container.add_class('vbox')\n",
141 "fill_container(container)\n",
148 "fill_container(container)\n",
142 "\n",
149 "\n",
143 "container = make_container('HBox')\n",
150 "container = make_container('HBox')\n",
144 "container.hbox()\n",
151 "container.add_class('hbox')\n",
145 "fill_container(container)\n"
152 "fill_container(container)\n"
146 ],
153 ],
147 "language": "python",
154 "language": "python",
@@ -161,18 +168,18 b''
161 "collapsed": false,
168 "collapsed": false,
162 "input": [
169 "input": [
163 "container = make_container('HBox Pack Start')\n",
170 "container = make_container('HBox Pack Start')\n",
164 "container.hbox()\n",
171 "container.add_class('hbox')\n",
165 "container.pack_start()\n",
172 "container.add_class('start')\n",
166 "fill_container(container)\n",
173 "fill_container(container)\n",
167 " \n",
174 " \n",
168 "container = make_container('HBox Pack Center')\n",
175 "container = make_container('HBox Pack Center')\n",
169 "container.hbox()\n",
176 "container.add_class('hbox')\n",
170 "container.pack_center()\n",
177 "container.add_class('center')\n",
171 "fill_container(container)\n",
178 "fill_container(container)\n",
172 " \n",
179 " \n",
173 "container = make_container('HBox Pack End')\n",
180 "container = make_container('HBox Pack End')\n",
174 "container.hbox()\n",
181 "container.add_class('hbox')\n",
175 "container.pack_end()\n",
182 "container.add_class('end')\n",
176 "fill_container(container)"
183 "fill_container(container)"
177 ],
184 ],
178 "language": "python",
185 "language": "python",
@@ -194,47 +201,49 b''
194 "def fill_container(container, flexes):\n",
201 "def fill_container(container, flexes):\n",
195 " components = []\n",
202 " components = []\n",
196 " for i in range(len(flexes)):\n",
203 " for i in range(len(flexes)):\n",
197 " components.append(widgets.ContainerWidget(parent=container))\n",
204 " components.append(widgets.ContainerWidget())\n",
198 " components[i].set_css(child_style)\n",
205 " components[i].set_css(child_style)\n",
199 " \n",
206 " \n",
200 " label = widgets.StringWidget(parent=components[i], default_view_name='HTMLView', value=str(flexes[i]))\n",
207 " label = widgets.LatexWidget(value=str(flexes[i]))\n",
208 " components[i].children = [label]\n",
209 " container.children = components\n",
201 " \n",
210 " \n",
211 " for i in range(len(flexes)):\n",
202 " if flexes[i] == 0:\n",
212 " if flexes[i] == 0:\n",
203 " components[i].flex0()\n",
213 " components[i].add_class('box-flex0')\n",
204 " elif flexes[i] == 1:\n",
214 " elif flexes[i] == 1:\n",
205 " components[i].flex1()\n",
215 " components[i].add_class('box-flex1')\n",
206 " elif flexes[i] == 2:\n",
216 " elif flexes[i] == 2:\n",
207 " components[i].flex2()\n",
217 " components[i].add_class('box-flex2')\n",
208 " container.children = components\n",
209 " \n",
218 " \n",
210 "container = make_container('Different Flex Configurations')\n",
219 "container = make_container('Different Flex Configurations')\n",
211 "container.hbox()\n",
220 "container.add_class('hbox')\n",
212 "fill_container(container, [0, 0, 0])\n",
221 "fill_container(container, [0, 0, 0])\n",
213 " \n",
222 " \n",
214 "container = make_container('')\n",
223 "container = make_container('')\n",
215 "container.hbox()\n",
224 "container.add_class('hbox')\n",
216 "fill_container(container, [0, 0, 1])\n",
225 "fill_container(container, [0, 0, 1])\n",
217 " \n",
226 " \n",
218 "container = make_container('')\n",
227 "container = make_container('')\n",
219 "container.hbox()\n",
228 "container.add_class('hbox')\n",
220 "fill_container(container, [0, 1, 1])\n",
229 "fill_container(container, [0, 1, 1])\n",
221 " \n",
230 " \n",
222 "container = make_container('')\n",
231 "container = make_container('')\n",
223 "container.hbox()\n",
232 "container.add_class('hbox')\n",
224 "fill_container(container, [0, 2, 2])\n",
233 "fill_container(container, [0, 2, 2])\n",
225 " \n",
234 " \n",
226 "container = make_container('')\n",
235 "container = make_container('')\n",
227 "container.hbox()\n",
236 "container.add_class('hbox')\n",
228 "fill_container(container, [0, 1, 2])\n",
237 "fill_container(container, [0, 1, 2])\n",
229 " \n",
238 " \n",
230 "container = make_container('')\n",
239 "container = make_container('')\n",
231 "container.hbox()\n",
240 "container.add_class('hbox')\n",
232 "fill_container(container, [1, 1, 2])"
241 "fill_container(container, [1, 1, 2])"
233 ],
242 ],
234 "language": "python",
243 "language": "python",
235 "metadata": {},
244 "metadata": {},
236 "outputs": [],
245 "outputs": [],
237 "prompt_number": 8
246 "prompt_number": 7
238 },
247 },
239 {
248 {
240 "cell_type": "markdown",
249 "cell_type": "markdown",
@@ -250,30 +259,30 b''
250 "def fill_container(container):\n",
259 "def fill_container(container):\n",
251 " components = []\n",
260 " components = []\n",
252 " for i in range(3):\n",
261 " for i in range(3):\n",
253 " components.append(widgets.StringWidget(parent=container, default_view_name='HTMLView', value=\"ABC\"[i]))\n",
262 " components.append(widgets.LatexWidget(parent=container, value=\"ABC\"[i]))\n",
254 " components[i].set_css(child_style)\n",
263 " components[i].set_css(child_style)\n",
255 " components[i].set_css('height', str((i+1) * 50) + 'px')\n",
264 " components[i].set_css('height', str((i+1) * 50) + 'px')\n",
256 " container.children = components\n",
265 " container.children = components\n",
257 "\n",
266 "\n",
258 "container = make_container('HBox Align Start')\n",
267 "container = make_container('HBox Align Start')\n",
259 "container.hbox()\n",
268 "container.add_class(\"hbox\")\n",
260 "container.align_start()\n",
269 "container.add_class(\"align-start\")\n",
261 "fill_container(container)\n",
270 "fill_container(container)\n",
262 " \n",
271 " \n",
263 "container = make_container('HBox Align Center')\n",
272 "container = make_container('HBox Align Center')\n",
264 "container.hbox()\n",
273 "container.add_class(\"hbox\")\n",
265 "container.align_center()\n",
274 "container.add_class(\"align-center\")\n",
266 "fill_container(container)\n",
275 "fill_container(container)\n",
267 " \n",
276 " \n",
268 "container = make_container('HBox Align End')\n",
277 "container = make_container('HBox Align End')\n",
269 "container.hbox()\n",
278 "container.add_class(\"hbox\")\n",
270 "container.align_end()\n",
279 "container.add_class(\"align-end\")\n",
271 "fill_container(container)"
280 "fill_container(container)"
272 ],
281 ],
273 "language": "python",
282 "language": "python",
274 "metadata": {},
283 "metadata": {},
275 "outputs": [],
284 "outputs": [],
276 "prompt_number": 9
285 "prompt_number": 8
277 },
286 },
278 {
287 {
279 "cell_type": "markdown",
288 "cell_type": "markdown",
@@ -287,23 +296,15 b''
287 "collapsed": false,
296 "collapsed": false,
288 "input": [
297 "input": [
289 "container = widgets.ContainerWidget()\n",
298 "container = widgets.ContainerWidget()\n",
290 "container.hbox()\n",
299 "container.children=[widgets.FloatSliderWidget(orientation='vertical', description=str(i+1), value=50.0) \n",
291 "container.children=[widgets.FloatRangeWidget(orientation='vertical', description=str(i+1), value=50.0) \n",
292 " for i in range(15)]\n",
300 " for i in range(15)]\n",
293 "display(container)"
301 "display(container)\n",
302 "container.add_class('hbox')"
294 ],
303 ],
295 "language": "python",
304 "language": "python",
296 "metadata": {},
305 "metadata": {},
297 "outputs": [],
306 "outputs": [],
298 "prompt_number": 11
307 "prompt_number": 9
299 },
300 {
301 "cell_type": "code",
302 "collapsed": false,
303 "input": [],
304 "language": "python",
305 "metadata": {},
306 "outputs": []
307 }
308 }
308 ],
309 ],
309 "metadata": {}
310 "metadata": {}
@@ -37,7 +37,7 b''
37 "language": "python",
37 "language": "python",
38 "metadata": {},
38 "metadata": {},
39 "outputs": [],
39 "outputs": [],
40 "prompt_number": 15
40 "prompt_number": 19
41 },
41 },
42 {
42 {
43 "cell_type": "markdown",
43 "cell_type": "markdown",
@@ -56,7 +56,7 b''
56 "language": "python",
56 "language": "python",
57 "metadata": {},
57 "metadata": {},
58 "outputs": [],
58 "outputs": [],
59 "prompt_number": 16
59 "prompt_number": 20
60 },
60 },
61 {
61 {
62 "cell_type": "heading",
62 "cell_type": "heading",
@@ -101,25 +101,23 b''
101 "collapsed": false,
101 "collapsed": false,
102 "input": [
102 "input": [
103 "# Import the base Widget class and the traitlets Unicode class.\n",
103 "# Import the base Widget class and the traitlets Unicode class.\n",
104 "from IPython.html.widgets import Widget\n",
104 "from IPython.html.widgets import DOMWidget\n",
105 "from IPython.utils.traitlets import Unicode\n",
105 "from IPython.utils.traitlets import Unicode\n",
106 "\n",
106 "\n",
107 "# Define our DateWidget and its target model and default view.\n",
107 "# Define our DateWidget and its target model and default view.\n",
108 "class DateWidget(Widget):\n",
108 "class DateWidget(DOMWidget):\n",
109 " target_name = Unicode('DateWidgetModel')\n",
109 " _view_name = Unicode('DatePickerView', sync=True)"
110 " default_view_name = Unicode('DatePickerView')"
111 ],
110 ],
112 "language": "python",
111 "language": "python",
113 "metadata": {},
112 "metadata": {},
114 "outputs": [],
113 "outputs": [],
115 "prompt_number": 17
114 "prompt_number": 21
116 },
115 },
117 {
116 {
118 "cell_type": "markdown",
117 "cell_type": "markdown",
119 "metadata": {},
118 "metadata": {},
120 "source": [
119 "source": [
121 "- **target_name** is a special `Widget` property that tells the widget framework which Backbone model in the front-end corresponds to this widget.\n",
120 "- **_view_name** is the default Backbone view to display when the user calls `display` to display an instance of this widget.\n"
122 "- **default_view_name** is the default Backbone view to display when the user calls `display` to display an instance of this widget.\n"
123 ]
121 ]
124 },
122 },
125 {
123 {
@@ -134,7 +132,7 b''
134 "cell_type": "markdown",
132 "cell_type": "markdown",
135 "metadata": {},
133 "metadata": {},
136 "source": [
134 "source": [
137 "In the IPython notebook [require.js](http://requirejs.org/) is used to load JavaScript dependencies. All IPython widget code depends on `notebook/js/widget.js`. In it the base widget model, base view, and widget manager are defined. We need to use require.js to include this file:"
135 "In the IPython notebook [require.js](http://requirejs.org/) is used to load JavaScript dependencies. All IPython widget code depends on `notebook/js/widgets/widget.js`. In it the base widget model and base view are defined. We need to use require.js to include this file:"
138 ]
136 ]
139 },
137 },
140 {
138 {
@@ -143,7 +141,7 b''
143 "input": [
141 "input": [
144 "%%javascript\n",
142 "%%javascript\n",
145 "\n",
143 "\n",
146 "require([\"notebook/js/widgets/\"], function(){\n",
144 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
147 "\n",
145 "\n",
148 "});"
146 "});"
149 ],
147 ],
@@ -153,66 +151,24 b''
153 {
151 {
154 "javascript": [
152 "javascript": [
155 "\n",
153 "\n",
156 "require([\"notebook/js/widget\"], function(){\n",
154 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
157 "\n",
155 "\n",
158 "});"
156 "});"
159 ],
157 ],
160 "metadata": {},
158 "metadata": {},
161 "output_type": "display_data",
159 "output_type": "display_data",
162 "text": [
160 "text": [
163 "<IPython.core.display.Javascript at 0x10a26a850>"
161 "<IPython.core.display.Javascript at 0x1e409d0>"
164 ]
162 ]
165 }
163 }
166 ],
164 ],
167 "prompt_number": 18
165 "prompt_number": 22
168 },
169 {
170 "cell_type": "markdown",
171 "metadata": {},
172 "source": [
173 "The next step is to add a definition for the widget's model. It's important to extend the `IPython.WidgetModel` which extends the Backbone.js base model instead of trying to extend the Backbone.js base model directly. After defining the model, it needs to be registed with the widget manager using the `target_name` used in the Python code."
174 ]
175 },
176 {
177 "cell_type": "code",
178 "collapsed": false,
179 "input": [
180 "%%javascript\n",
181 "\n",
182 "require([\"notebook/js/widgets/base\"], function(){\n",
183 " \n",
184 " // Define the DateModel and register it with the widget manager.\n",
185 " var DateModel = IPython.WidgetModel.extend({});\n",
186 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
187 "});"
188 ],
189 "language": "python",
190 "metadata": {},
191 "outputs": [
192 {
193 "javascript": [
194 "\n",
195 "require([\"notebook/js/widgets/base\"], function(){\n",
196 " \n",
197 " // Define the DateModel and register it with the widget manager.\n",
198 " var DateModel = IPython.WidgetModel.extend({});\n",
199 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
200 "});"
201 ],
202 "metadata": {},
203 "output_type": "display_data",
204 "text": [
205 "<IPython.core.display.Javascript at 0x10a26aa10>"
206 ]
207 }
208 ],
209 "prompt_number": 20
210 },
166 },
211 {
167 {
212 "cell_type": "markdown",
168 "cell_type": "markdown",
213 "metadata": {},
169 "metadata": {},
214 "source": [
170 "source": [
215 "Now that the model is defined, we need to define a view that can be used to represent the model. To do this, the `IPython.WidgetView` is extended. A render function must be defined. The render function is used to render a widget view instance to the DOM. For now the render function renders a div that contains the text *Hello World!* Lastly, the view needs to be registered with the widget manager like the model was.\n",
171 "Now we need to define a view that can be used to represent the model. To do this, the `IPython.DOMWidgetView` is extended. A render function must be defined. The render function is used to render a widget view instance to the DOM. For now the render function renders a div that contains the text *Hello World!* Lastly, the view needs to be registered with the widget manager like the model was.\n",
216 "\n",
172 "\n",
217 "**Final JavaScript code below:**"
173 "**Final JavaScript code below:**"
218 ]
174 ]
@@ -223,23 +179,15 b''
223 "input": [
179 "input": [
224 "%%javascript\n",
180 "%%javascript\n",
225 "\n",
181 "\n",
226 "require([\"notebook/js/widgets/base\"], function(){\n",
182 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
227 " \n",
228 " // Define the DateModel and register it with the widget manager.\n",
229 " var DateModel = IPython.WidgetModel.extend({});\n",
230 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
231 " \n",
183 " \n",
232 " // Define the DatePickerView\n",
184 " // Define the DatePickerView\n",
233 " var DatePickerView = IPython.WidgetView.extend({\n",
185 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
234 " \n",
186 " render: function(){ this.$el.text('Hello World!'); },\n",
235 " render: function(){\n",
236 " this.$el = $('<div />')\n",
237 " .html('Hello World!');\n",
238 " },\n",
239 " });\n",
187 " });\n",
240 " \n",
188 " \n",
241 " // Register the DatePickerView with the widget manager.\n",
189 " // Register the DatePickerView with the widget manager.\n",
242 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
190 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
243 "});"
191 "});"
244 ],
192 ],
245 "language": "python",
193 "language": "python",
@@ -248,29 +196,21 b''
248 {
196 {
249 "javascript": [
197 "javascript": [
250 "\n",
198 "\n",
251 "require([\"notebook/js/widgets/base\"], function(){\n",
199 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
252 " \n",
253 " // Define the DateModel and register it with the widget manager.\n",
254 " var DateModel = IPython.WidgetModel.extend({});\n",
255 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
256 " \n",
200 " \n",
257 " // Define the DatePickerView\n",
201 " // Define the DatePickerView\n",
258 " var DatePickerView = IPython.WidgetView.extend({\n",
202 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
259 " \n",
203 " render: function(){ this.$el.text('Hello World!'); },\n",
260 " render: function(){\n",
261 " this.$el = $('<div />')\n",
262 " .html('Hello World!');\n",
263 " },\n",
264 " });\n",
204 " });\n",
265 " \n",
205 " \n",
266 " // Register the DatePickerView with the widget manager.\n",
206 " // Register the DatePickerView with the widget manager.\n",
267 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
207 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
268 "});"
208 "});"
269 ],
209 ],
270 "metadata": {},
210 "metadata": {},
271 "output_type": "display_data",
211 "output_type": "display_data",
272 "text": [
212 "text": [
273 "<IPython.core.display.Javascript at 0x10a26ae90>"
213 "<IPython.core.display.Javascript at 0x1e40a50>"
274 ]
214 ]
275 }
215 }
276 ],
216 ],
@@ -295,8 +235,7 b''
295 "cell_type": "code",
235 "cell_type": "code",
296 "collapsed": false,
236 "collapsed": false,
297 "input": [
237 "input": [
298 "my_widget = DateWidget()\n",
238 "DateWidget()"
299 "display(my_widget)"
300 ],
239 ],
301 "language": "python",
240 "language": "python",
302 "metadata": {},
241 "metadata": {},
@@ -323,7 +262,7 b''
323 "cell_type": "markdown",
262 "cell_type": "markdown",
324 "metadata": {},
263 "metadata": {},
325 "source": [
264 "source": [
326 "In the last section we created a simple widget that displayed *Hello World!* There was no custom state information associated with the widget. To make an actual date widget, we need to add a property that will be synced between the Python model and the JavaScript model. The new property must be a traitlet property so the widget machinery can automatically handle it. The property needs to be added to the the `_keys` list. The `_keys` list tells the widget machinery what traitlets should be synced with the front-end. Adding this to the code from the last section:"
265 "In the last section we created a simple widget that displayed *Hello World!* To make an actual date widget, we need to add a property that will be synced between the Python model and the JavaScript model. The new property must be a traitlet property so the widget machinery can automatically handle it. The property needs to be constructed with a `sync=True` keyword argument so the widget machinery knows to syncronize it with the fron-end. Adding this to the code from the last section:"
327 ]
266 ]
328 },
267 },
329 {
268 {
@@ -331,17 +270,13 b''
331 "collapsed": false,
270 "collapsed": false,
332 "input": [
271 "input": [
333 "# Import the base Widget class and the traitlets Unicode class.\n",
272 "# Import the base Widget class and the traitlets Unicode class.\n",
334 "from IPython.html.widgets import Widget\n",
273 "from IPython.html.widgets import DOMWidget\n",
335 "from IPython.utils.traitlets import Unicode\n",
274 "from IPython.utils.traitlets import Unicode\n",
336 "\n",
275 "\n",
337 "# Define our DateWidget and its target model and default view.\n",
276 "# Define our DateWidget and its target model and default view.\n",
338 "class DateWidget(Widget):\n",
277 "class DateWidget(DOMWidget):\n",
339 " target_name = Unicode('DateWidgetModel')\n",
278 " _view_name = Unicode('DatePickerView', sync=True)\n",
340 " default_view_name = Unicode('DatePickerView')\n",
279 " value = Unicode(sync=True)"
341 " \n",
342 " # Define the custom state properties to sync with the front-end\n",
343 " _keys = ['value']\n",
344 " value = Unicode()"
345 ],
280 ],
346 "language": "python",
281 "language": "python",
347 "metadata": {},
282 "metadata": {},
@@ -369,28 +304,21 b''
369 "input": [
304 "input": [
370 "%%javascript\n",
305 "%%javascript\n",
371 "\n",
306 "\n",
372 "require([\"notebook/js/widgets/base\"], function(){\n",
307 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
373 " \n",
374 " // Define the DateModel and register it with the widget manager.\n",
375 " var DateModel = IPython.WidgetModel.extend({});\n",
376 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
377 " \n",
308 " \n",
378 " // Define the DatePickerView\n",
309 " // Define the DatePickerView\n",
379 " var DatePickerView = IPython.WidgetView.extend({\n",
310 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
380 " \n",
381 " render: function(){\n",
311 " render: function(){\n",
382 " \n",
312 " \n",
383 " // Create a div to hold our widget.\n",
384 " this.$el = $('<div />');\n",
385 " \n",
386 " // Create the date picker control.\n",
313 " // Create the date picker control.\n",
387 " this.$date = $('<input />')\n",
314 " this.$date = $('<input />')\n",
388 " .attr('type', 'date');\n",
315 " .attr('type', 'date')\n",
316 " .appendTo(this.$el);\n",
389 " },\n",
317 " },\n",
390 " });\n",
318 " });\n",
391 " \n",
319 " \n",
392 " // Register the DatePickerView with the widget manager.\n",
320 " // Register the DatePickerView with the widget manager.\n",
393 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
321 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
394 "});"
322 "});"
395 ],
323 ],
396 "language": "python",
324 "language": "python",
@@ -399,34 +327,27 b''
399 {
327 {
400 "javascript": [
328 "javascript": [
401 "\n",
329 "\n",
402 "require([\"notebook/js/widgets/base\"], function(){\n",
330 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
403 " \n",
404 " // Define the DateModel and register it with the widget manager.\n",
405 " var DateModel = IPython.WidgetModel.extend({});\n",
406 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
407 " \n",
331 " \n",
408 " // Define the DatePickerView\n",
332 " // Define the DatePickerView\n",
409 " var DatePickerView = IPython.WidgetView.extend({\n",
333 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
410 " \n",
411 " render: function(){\n",
334 " render: function(){\n",
412 " \n",
335 " \n",
413 " // Create a div to hold our widget.\n",
414 " this.$el = $('<div />');\n",
415 " \n",
416 " // Create the date picker control.\n",
336 " // Create the date picker control.\n",
417 " this.$date = $('<input />')\n",
337 " this.$date = $('<input />')\n",
418 " .attr('type', 'date');\n",
338 " .attr('type', 'date')\n",
339 " .appendTo(this.$el);\n",
419 " },\n",
340 " },\n",
420 " });\n",
341 " });\n",
421 " \n",
342 " \n",
422 " // Register the DatePickerView with the widget manager.\n",
343 " // Register the DatePickerView with the widget manager.\n",
423 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
344 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
424 "});"
345 "});"
425 ],
346 ],
426 "metadata": {},
347 "metadata": {},
427 "output_type": "display_data",
348 "output_type": "display_data",
428 "text": [
349 "text": [
429 "<IPython.core.display.Javascript at 0x10a274050>"
350 "<IPython.core.display.Javascript at 0x1e40810>"
430 ]
351 ]
431 }
352 }
432 ],
353 ],
@@ -445,35 +366,28 b''
445 "input": [
366 "input": [
446 "%%javascript\n",
367 "%%javascript\n",
447 "\n",
368 "\n",
448 "require([\"notebook/js/widgets/base\"], function(){\n",
369 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
449 " \n",
450 " // Define the DateModel and register it with the widget manager.\n",
451 " var DateModel = IPython.WidgetModel.extend({});\n",
452 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
453 " \n",
370 " \n",
454 " // Define the DatePickerView\n",
371 " // Define the DatePickerView\n",
455 " var DatePickerView = IPython.WidgetView.extend({\n",
372 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
456 " \n",
457 " render: function(){\n",
373 " render: function(){\n",
458 " \n",
374 " \n",
459 " // Create a div to hold our widget.\n",
460 " this.$el = $('<div />');\n",
461 " \n",
462 " // Create the date picker control.\n",
375 " // Create the date picker control.\n",
463 " this.$date = $('<input />')\n",
376 " this.$date = $('<input />')\n",
464 " .attr('type', 'date');\n",
377 " .attr('type', 'date')\n",
378 " .appendTo(this.$el);\n",
465 " },\n",
379 " },\n",
466 " \n",
380 " \n",
467 " update: function() {\n",
381 " update: function() {\n",
468 " \n",
382 " \n",
469 " // Set the value of the date control and then call base.\n",
383 " // Set the value of the date control and then call base.\n",
470 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
384 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
471 " return IPython.WidgetView.prototype.update.call(this);\n",
385 " return DatePickerView.__super__.update.apply(this);\n",
472 " },\n",
386 " },\n",
473 " });\n",
387 " });\n",
474 " \n",
388 " \n",
475 " // Register the DatePickerView with the widget manager.\n",
389 " // Register the DatePickerView with the widget manager.\n",
476 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
390 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
477 "});"
391 "});"
478 ],
392 ],
479 "language": "python",
393 "language": "python",
@@ -482,41 +396,34 b''
482 {
396 {
483 "javascript": [
397 "javascript": [
484 "\n",
398 "\n",
485 "require([\"notebook/js/widgets/base\"], function(){\n",
399 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
486 " \n",
487 " // Define the DateModel and register it with the widget manager.\n",
488 " var DateModel = IPython.WidgetModel.extend({});\n",
489 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
490 " \n",
400 " \n",
491 " // Define the DatePickerView\n",
401 " // Define the DatePickerView\n",
492 " var DatePickerView = IPython.WidgetView.extend({\n",
402 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
493 " \n",
494 " render: function(){\n",
403 " render: function(){\n",
495 " \n",
404 " \n",
496 " // Create a div to hold our widget.\n",
497 " this.$el = $('<div />');\n",
498 " \n",
499 " // Create the date picker control.\n",
405 " // Create the date picker control.\n",
500 " this.$date = $('<input />')\n",
406 " this.$date = $('<input />')\n",
501 " .attr('type', 'date');\n",
407 " .attr('type', 'date')\n",
408 " .appendTo(this.$el);\n",
502 " },\n",
409 " },\n",
503 " \n",
410 " \n",
504 " update: function() {\n",
411 " update: function() {\n",
505 " \n",
412 " \n",
506 " // Set the value of the date control and then call base.\n",
413 " // Set the value of the date control and then call base.\n",
507 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
414 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
508 " return IPython.WidgetView.prototype.update.call(this);\n",
415 " return DatePickerView.__super__.update.apply(this);\n",
509 " },\n",
416 " },\n",
510 " });\n",
417 " });\n",
511 " \n",
418 " \n",
512 " // Register the DatePickerView with the widget manager.\n",
419 " // Register the DatePickerView with the widget manager.\n",
513 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
420 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
514 "});"
421 "});"
515 ],
422 ],
516 "metadata": {},
423 "metadata": {},
517 "output_type": "display_data",
424 "output_type": "display_data",
518 "text": [
425 "text": [
519 "<IPython.core.display.Javascript at 0x10a2740d0>"
426 "<IPython.core.display.Javascript at 0x1e40390>"
520 ]
427 ]
521 }
428 }
522 ],
429 ],
@@ -526,9 +433,7 b''
526 "cell_type": "markdown",
433 "cell_type": "markdown",
527 "metadata": {},
434 "metadata": {},
528 "source": [
435 "source": [
529 "To get the changed value from the front-end to publish itself to the back-end, we need to listen to the change event triggered by the HTM date control and set the value in the model. By setting the `this.$el` property of the view, we break the Backbone powered event handling. To fix this, a call to `this.delegateEvents()` must be added after `this.$el` is set. \n",
436 "To get the changed value from the front-end to publish itself to the back-end, we need to listen to the change event triggered by the HTM date control and set the value in the model. After the date change event fires and the new value is set in the model, it's very important that we call `this.touch()` to let the widget machinery know which view changed the model. This is important because the widget machinery needs to know which cell to route the message callbacks to.\n",
530 "\n",
531 "After the date change event fires and the new value is set in the model, it's very important that we call `update_other_views(this)` to make the other views on the page update and to let the widget machinery know which view changed the model. This is important because the widget machinery needs to know which cell to route the message callbacks to.\n",
532 "\n",
437 "\n",
533 "**Final JavaScript code below:**"
438 "**Final JavaScript code below:**"
534 ]
439 ]
@@ -539,21 +444,13 b''
539 "input": [
444 "input": [
540 "%%javascript\n",
445 "%%javascript\n",
541 "\n",
446 "\n",
542 "require([\"notebook/js/widgets/base\"], function(){\n",
447 "\n",
543 " \n",
448 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
544 " // Define the DateModel and register it with the widget manager.\n",
545 " var DateModel = IPython.WidgetModel.extend({});\n",
546 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
547 " \n",
449 " \n",
548 " // Define the DatePickerView\n",
450 " // Define the DatePickerView\n",
549 " var DatePickerView = IPython.WidgetView.extend({\n",
451 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
550 " \n",
551 " render: function(){\n",
452 " render: function(){\n",
552 " \n",
453 " \n",
553 " // Create a div to hold our widget.\n",
554 " this.$el = $('<div />');\n",
555 " this.delegateEvents();\n",
556 " \n",
557 " // Create the date picker control.\n",
454 " // Create the date picker control.\n",
558 " this.$date = $('<input />')\n",
455 " this.$date = $('<input />')\n",
559 " .attr('type', 'date')\n",
456 " .attr('type', 'date')\n",
@@ -564,7 +461,7 b''
564 " \n",
461 " \n",
565 " // Set the value of the date control and then call base.\n",
462 " // Set the value of the date control and then call base.\n",
566 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
463 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
567 " return IPython.WidgetView.prototype.update.call(this);\n",
464 " return DatePickerView.__super__.update.apply(this);\n",
568 " },\n",
465 " },\n",
569 " \n",
466 " \n",
570 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
467 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
@@ -573,12 +470,12 b''
573 " // Callback for when the date is changed.\n",
470 " // Callback for when the date is changed.\n",
574 " handle_date_change: function(event) {\n",
471 " handle_date_change: function(event) {\n",
575 " this.model.set('value', this.$date.val());\n",
472 " this.model.set('value', this.$date.val());\n",
473 " this.touch();\n",
576 " },\n",
474 " },\n",
577 " \n",
578 " });\n",
475 " });\n",
579 " \n",
476 " \n",
580 " // Register the DatePickerView with the widget manager.\n",
477 " // Register the DatePickerView with the widget manager.\n",
581 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
478 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
582 "});"
479 "});"
583 ],
480 ],
584 "language": "python",
481 "language": "python",
@@ -587,21 +484,13 b''
587 {
484 {
588 "javascript": [
485 "javascript": [
589 "\n",
486 "\n",
590 "require([\"notebook/js/widgets/base\"], function(){\n",
487 "\n",
591 " \n",
488 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
592 " // Define the DateModel and register it with the widget manager.\n",
593 " var DateModel = IPython.WidgetModel.extend({});\n",
594 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
595 " \n",
489 " \n",
596 " // Define the DatePickerView\n",
490 " // Define the DatePickerView\n",
597 " var DatePickerView = IPython.WidgetView.extend({\n",
491 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
598 " \n",
599 " render: function(){\n",
492 " render: function(){\n",
600 " \n",
493 " \n",
601 " // Create a div to hold our widget.\n",
602 " this.$el = $('<div />');\n",
603 " this.delegateEvents();\n",
604 " \n",
605 " // Create the date picker control.\n",
494 " // Create the date picker control.\n",
606 " this.$date = $('<input />')\n",
495 " this.$date = $('<input />')\n",
607 " .attr('type', 'date')\n",
496 " .attr('type', 'date')\n",
@@ -612,7 +501,7 b''
612 " \n",
501 " \n",
613 " // Set the value of the date control and then call base.\n",
502 " // Set the value of the date control and then call base.\n",
614 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
503 " this.$date.val(this.model.get('value')); // ISO format \"YYYY-MM-DDTHH:mm:ss.sssZ\" is required\n",
615 " return IPython.WidgetView.prototype.update.call(this);\n",
504 " return DatePickerView.__super__.update.apply(this);\n",
616 " },\n",
505 " },\n",
617 " \n",
506 " \n",
618 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
507 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
@@ -621,22 +510,22 b''
621 " // Callback for when the date is changed.\n",
510 " // Callback for when the date is changed.\n",
622 " handle_date_change: function(event) {\n",
511 " handle_date_change: function(event) {\n",
623 " this.model.set('value', this.$date.val());\n",
512 " this.model.set('value', this.$date.val());\n",
513 " this.touch();\n",
624 " },\n",
514 " },\n",
625 " \n",
626 " });\n",
515 " });\n",
627 " \n",
516 " \n",
628 " // Register the DatePickerView with the widget manager.\n",
517 " // Register the DatePickerView with the widget manager.\n",
629 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
518 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
630 "});"
519 "});"
631 ],
520 ],
632 "metadata": {},
521 "metadata": {},
633 "output_type": "display_data",
522 "output_type": "display_data",
634 "text": [
523 "text": [
635 "<IPython.core.display.Javascript at 0x10a274a10>"
524 "<IPython.core.display.Javascript at 0x1e40890>"
636 ]
525 ]
637 }
526 }
638 ],
527 ],
639 "prompt_number": 52
528 "prompt_number": 28
640 },
529 },
641 {
530 {
642 "cell_type": "heading",
531 "cell_type": "heading",
@@ -676,7 +565,7 b''
676 "cell_type": "code",
565 "cell_type": "code",
677 "collapsed": false,
566 "collapsed": false,
678 "input": [
567 "input": [
679 "display(my_widget)"
568 "my_widget"
680 ],
569 ],
681 "language": "python",
570 "language": "python",
682 "metadata": {},
571 "metadata": {},
@@ -702,13 +591,13 b''
702 {
591 {
703 "metadata": {},
592 "metadata": {},
704 "output_type": "pyout",
593 "output_type": "pyout",
705 "prompt_number": 37,
594 "prompt_number": 31,
706 "text": [
595 "text": [
707 "u'1998-12-01'"
596 "u''"
708 ]
597 ]
709 }
598 }
710 ],
599 ],
711 "prompt_number": 37
600 "prompt_number": 31
712 },
601 },
713 {
602 {
714 "cell_type": "markdown",
603 "cell_type": "markdown",
@@ -726,7 +615,7 b''
726 "language": "python",
615 "language": "python",
727 "metadata": {},
616 "metadata": {},
728 "outputs": [],
617 "outputs": [],
729 "prompt_number": 34
618 "prompt_number": 32
730 },
619 },
731 {
620 {
732 "cell_type": "heading",
621 "cell_type": "heading",
@@ -763,17 +652,13 b''
763 "collapsed": false,
652 "collapsed": false,
764 "input": [
653 "input": [
765 "# Import the base Widget class and the traitlets Unicode class.\n",
654 "# Import the base Widget class and the traitlets Unicode class.\n",
766 "from IPython.html.widgets import Widget\n",
655 "from IPython.html.widgets import DOMWidget\n",
767 "from IPython.utils.traitlets import Unicode\n",
656 "from IPython.utils.traitlets import Unicode\n",
768 "\n",
657 "\n",
769 "# Define our DateWidget and its target model and default view.\n",
658 "# Define our DateWidget and its target model and default view.\n",
770 "class DateWidget(Widget):\n",
659 "class DateWidget(DOMWidget):\n",
771 " target_name = Unicode('DateWidgetModel')\n",
660 " _view_name = Unicode('DatePickerView', sync=True)\n",
772 " default_view_name = Unicode('DatePickerView')\n",
661 " value = Unicode(sync=True)\n",
773 " \n",
774 " # Define the custom state properties to sync with the front-end\n",
775 " _keys = ['value']\n",
776 " value = Unicode()\n",
777 " \n",
662 " \n",
778 " # This function automatically gets called by the traitlet machinery when\n",
663 " # This function automatically gets called by the traitlet machinery when\n",
779 " # value is modified because of this function's name.\n",
664 " # value is modified because of this function's name.\n",
@@ -784,7 +669,7 b''
784 "language": "python",
669 "language": "python",
785 "metadata": {},
670 "metadata": {},
786 "outputs": [],
671 "outputs": [],
787 "prompt_number": 38
672 "prompt_number": 33
788 },
673 },
789 {
674 {
790 "cell_type": "markdown",
675 "cell_type": "markdown",
@@ -797,19 +682,17 b''
797 "cell_type": "code",
682 "cell_type": "code",
798 "collapsed": false,
683 "collapsed": false,
799 "input": [
684 "input": [
685 "# Import the dateutil library to parse date strings.\n",
686 "from dateutil import parser\n",
800 "\n",
687 "\n",
801 "# Import the base Widget class and the traitlets Unicode class.\n",
688 "# Import the base Widget class and the traitlets Unicode class.\n",
802 "from IPython.html.widgets import Widget\n",
689 "from IPython.html.widgets import DOMWidget\n",
803 "from IPython.utils.traitlets import Unicode\n",
690 "from IPython.utils.traitlets import Unicode\n",
804 "\n",
691 "\n",
805 "# Define our DateWidget and its target model and default view.\n",
692 "# Define our DateWidget and its target model and default view.\n",
806 "class DateWidget(Widget):\n",
693 "class DateWidget(DOMWidget):\n",
807 " target_name = Unicode('DateWidgetModel')\n",
694 " _view_name = Unicode('DatePickerView', sync=True)\n",
808 " default_view_name = Unicode('DatePickerView')\n",
695 " value = Unicode(sync=True)\n",
809 " \n",
810 " # Define the custom state properties to sync with the front-end\n",
811 " _keys = ['value']\n",
812 " value = Unicode()\n",
813 " \n",
696 " \n",
814 " # This function automatically gets called by the traitlet machinery when\n",
697 " # This function automatically gets called by the traitlet machinery when\n",
815 " # value is modified because of this function's name.\n",
698 " # value is modified because of this function's name.\n",
@@ -829,7 +712,7 b''
829 "language": "python",
712 "language": "python",
830 "metadata": {},
713 "metadata": {},
831 "outputs": [],
714 "outputs": [],
832 "prompt_number": 39
715 "prompt_number": 34
833 },
716 },
834 {
717 {
835 "cell_type": "markdown",
718 "cell_type": "markdown",
@@ -846,18 +729,14 b''
846 "from dateutil import parser\n",
729 "from dateutil import parser\n",
847 "\n",
730 "\n",
848 "# Import the base Widget class and the traitlets Unicode class.\n",
731 "# Import the base Widget class and the traitlets Unicode class.\n",
849 "from IPython.html.widgets import Widget\n",
732 "from IPython.html.widgets import DOMWidget\n",
850 "from IPython.utils.traitlets import Unicode\n",
733 "from IPython.utils.traitlets import Unicode\n",
851 "\n",
734 "\n",
852 "# Define our DateWidget and its target model and default view.\n",
735 "# Define our DateWidget and its target model and default view.\n",
853 "class DateWidget(Widget):\n",
736 "class DateWidget(DOMWidget):\n",
854 " target_name = Unicode('DateWidgetModel')\n",
737 " _view_name = Unicode('DatePickerView', sync=True)\n",
855 " default_view_name = Unicode('DatePickerView')\n",
738 " value = Unicode(sync=True)\n",
856 " \n",
739 " description = Unicode(sync=True)\n",
857 " # Define the custom state properties to sync with the front-end\n",
858 " _keys = ['value', 'description']\n",
859 " value = Unicode()\n",
860 " description = Unicode()\n",
861 " \n",
740 " \n",
862 " # This function automatically gets called by the traitlet machinery when\n",
741 " # This function automatically gets called by the traitlet machinery when\n",
863 " # value is modified because of this function's name.\n",
742 " # value is modified because of this function's name.\n",
@@ -877,7 +756,7 b''
877 "language": "python",
756 "language": "python",
878 "metadata": {},
757 "metadata": {},
879 "outputs": [],
758 "outputs": [],
880 "prompt_number": 40
759 "prompt_number": 35
881 },
760 },
882 {
761 {
883 "cell_type": "markdown",
762 "cell_type": "markdown",
@@ -896,22 +775,22 b''
896 "from dateutil import parser\n",
775 "from dateutil import parser\n",
897 "\n",
776 "\n",
898 "# Import the base Widget class and the traitlets Unicode class.\n",
777 "# Import the base Widget class and the traitlets Unicode class.\n",
899 "from IPython.html.widgets import Widget\n",
778 "from IPython.html.widgets import DOMWidget, CallbackDispatcher\n",
900 "from IPython.utils.traitlets import Unicode\n",
779 "from IPython.utils.traitlets import Unicode\n",
901 "\n",
780 "\n",
902 "# Define our DateWidget and its target model and default view.\n",
781 "# Define our DateWidget and its target model and default view.\n",
903 "class DateWidget(Widget):\n",
782 "class DateWidget(DOMWidget):\n",
904 " target_name = Unicode('DateWidgetModel')\n",
783 " _view_name = Unicode('DatePickerView', sync=True)\n",
905 " default_view_name = Unicode('DatePickerView')\n",
784 " value = Unicode(sync=True)\n",
906 " \n",
785 " description = Unicode(sync=True)\n",
907 " # Define the custom state properties to sync with the front-end\n",
908 " _keys = ['value', 'description']\n",
909 " value = Unicode()\n",
910 " description = Unicode()\n",
911 " \n",
786 " \n",
912 " def __init__(self, **kwargs):\n",
787 " def __init__(self, **kwargs):\n",
913 " super(DateWidget, self).__init__(**kwargs)\n",
788 " super(DateWidget, self).__init__(**kwargs)\n",
914 " self._validation_callbacks = []\n",
789 " \n",
790 " # Specify the number of positional arguments supported. For \n",
791 " # validation we only are worried about one parameter, the\n",
792 " # new value that should be validated.\n",
793 " self.validation = CallbackDispatcher(acceptable_nargs=[1])\n",
915 " \n",
794 " \n",
916 " # This function automatically gets called by the traitlet machinery when\n",
795 " # This function automatically gets called by the traitlet machinery when\n",
917 " # value is modified because of this function's name.\n",
796 " # value is modified because of this function's name.\n",
@@ -922,40 +801,23 b''
922 " parsed_date = parser.parse(new_value)\n",
801 " parsed_date = parser.parse(new_value)\n",
923 " parsed_date_string = parsed_date.strftime(\"%Y-%m-%d\")\n",
802 " parsed_date_string = parsed_date.strftime(\"%Y-%m-%d\")\n",
924 " except:\n",
803 " except:\n",
925 " parsed_date = None\n",
926 " parsed_date_string = ''\n",
804 " parsed_date_string = ''\n",
927 " \n",
805 " \n",
928 " # Set the parsed date string if the current date string is different.\n",
806 " # Set the parsed date string if the current date string is different.\n",
929 " if old_value != new_value:\n",
807 " if old_value != new_value:\n",
930 " if self.handle_validate(parsed_date):\n",
808 " validation = self.validation(parsed_date)\n",
809 " if validation is None or validation == True:\n",
931 " self.value = parsed_date_string\n",
810 " self.value = parsed_date_string\n",
932 " else:\n",
811 " else:\n",
933 " self.value = old_value\n",
812 " self.value = old_value\n",
934 " self.send_state() # The traitlet event won't fire since the value isn't changing.\n",
813 " self.send_state() # The traitlet event won't fire since the value isn't changing.\n",
935 " # We need to force the back-end to send the front-end the state\n",
814 " # We need to force the back-end to send the front-end the state\n",
936 " # to make sure that the date control date doesn't change.\n",
815 " # to make sure that the date control date doesn't change."
937 " \n",
938 " \n",
939 " # Allow the user to register custom validation callbacks.\n",
940 " # callback(new value as a datetime object)\n",
941 " def on_validate(self, callback, remove=False):\n",
942 " if remove and callback in self._validation_callbacks:\n",
943 " self._validation_callbacks.remove(callback)\n",
944 " elif (not remove) and (not callback in self._validation_callbacks):\n",
945 " self._validation_callbacks.append(callback)\n",
946 " \n",
947 " # Call user validation callbacks. Return True if valid.\n",
948 " def handle_validate(self, new_value):\n",
949 " for callback in self._validation_callbacks:\n",
950 " if not callback(new_value):\n",
951 " return False\n",
952 " return True\n",
953 " "
954 ],
816 ],
955 "language": "python",
817 "language": "python",
956 "metadata": {},
818 "metadata": {},
957 "outputs": [],
819 "outputs": [],
958 "prompt_number": 41
820 "prompt_number": 45
959 },
821 },
960 {
822 {
961 "cell_type": "heading",
823 "cell_type": "heading",
@@ -980,23 +842,14 b''
980 "input": [
842 "input": [
981 "%%javascript\n",
843 "%%javascript\n",
982 "\n",
844 "\n",
983 "require([\"notebook/js/widgets/base\"], function(){\n",
845 "\n",
984 " \n",
846 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
985 " // Define the DateModel and register it with the widget manager.\n",
986 " var DateModel = IPython.WidgetModel.extend({});\n",
987 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
988 " \n",
847 " \n",
989 " // Define the DatePickerView\n",
848 " // Define the DatePickerView\n",
990 " var DatePickerView = IPython.WidgetView.extend({\n",
849 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
991 " \n",
992 " render: function(){\n",
850 " render: function(){\n",
993 " \n",
851 " this.$el.addClass('widget-hbox-single'); /* Apply this class to the widget container to make\n",
994 " // Create a div to hold our widget.\n",
852 " it fit with the other built in widgets.*/\n",
995 " this.$el = $('<div />')\n",
996 " .addClass('widget-hbox-single'); // Apply this class to the widget container to make\n",
997 " // it fit with the other built in widgets.\n",
998 " this.delegateEvents();\n",
999 " \n",
1000 " // Create a label.\n",
853 " // Create a label.\n",
1001 " this.$label = $('<div />')\n",
854 " this.$label = $('<div />')\n",
1002 " .addClass('widget-hlabel')\n",
855 " .addClass('widget-hlabel')\n",
@@ -1020,10 +873,10 b''
1020 " this.$label.hide();\n",
873 " this.$label.hide();\n",
1021 " } else {\n",
874 " } else {\n",
1022 " this.$label.show();\n",
875 " this.$label.show();\n",
1023 " this.$label.html(description);\n",
876 " this.$label.text(description);\n",
1024 " }\n",
877 " }\n",
1025 " \n",
878 " \n",
1026 " return IPython.WidgetView.prototype.update.call(this);\n",
879 " return DatePickerView.__super__.update.apply(this);\n",
1027 " },\n",
880 " },\n",
1028 " \n",
881 " \n",
1029 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
882 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
@@ -1032,12 +885,12 b''
1032 " // Callback for when the date is changed.\n",
885 " // Callback for when the date is changed.\n",
1033 " handle_date_change: function(event) {\n",
886 " handle_date_change: function(event) {\n",
1034 " this.model.set('value', this.$date.val());\n",
887 " this.model.set('value', this.$date.val());\n",
888 " this.touch();\n",
1035 " },\n",
889 " },\n",
1036 " \n",
1037 " });\n",
890 " });\n",
1038 " \n",
891 " \n",
1039 " // Register the DatePickerView with the widget manager.\n",
892 " // Register the DatePickerView with the widget manager.\n",
1040 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
893 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
1041 "});"
894 "});"
1042 ],
895 ],
1043 "language": "python",
896 "language": "python",
@@ -1046,23 +899,14 b''
1046 {
899 {
1047 "javascript": [
900 "javascript": [
1048 "\n",
901 "\n",
1049 "require([\"notebook/js/widgets/base\"], function(){\n",
902 "\n",
1050 " \n",
903 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
1051 " // Define the DateModel and register it with the widget manager.\n",
1052 " var DateModel = IPython.WidgetModel.extend({});\n",
1053 " IPython.widget_manager.register_widget_model('DateWidgetModel', DateModel);\n",
1054 " \n",
904 " \n",
1055 " // Define the DatePickerView\n",
905 " // Define the DatePickerView\n",
1056 " var DatePickerView = IPython.WidgetView.extend({\n",
906 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
1057 " \n",
1058 " render: function(){\n",
907 " render: function(){\n",
1059 " \n",
908 " this.$el.addClass('widget-hbox-single'); /* Apply this class to the widget container to make\n",
1060 " // Create a div to hold our widget.\n",
909 " it fit with the other built in widgets.*/\n",
1061 " this.$el = $('<div />')\n",
1062 " .addClass('widget-hbox-single'); // Apply this class to the widget container to make\n",
1063 " // it fit with the other built in widgets.\n",
1064 " this.delegateEvents();\n",
1065 " \n",
1066 " // Create a label.\n",
910 " // Create a label.\n",
1067 " this.$label = $('<div />')\n",
911 " this.$label = $('<div />')\n",
1068 " .addClass('widget-hlabel')\n",
912 " .addClass('widget-hlabel')\n",
@@ -1086,10 +930,10 b''
1086 " this.$label.hide();\n",
930 " this.$label.hide();\n",
1087 " } else {\n",
931 " } else {\n",
1088 " this.$label.show();\n",
932 " this.$label.show();\n",
1089 " this.$label.html(description);\n",
933 " this.$label.text(description);\n",
1090 " }\n",
934 " }\n",
1091 " \n",
935 " \n",
1092 " return IPython.WidgetView.prototype.update.call(this);\n",
936 " return DatePickerView.__super__.update.apply(this);\n",
1093 " },\n",
937 " },\n",
1094 " \n",
938 " \n",
1095 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
939 " // Tell Backbone to listen to the change event of input controls (which the HTML date picker is)\n",
@@ -1098,22 +942,22 b''
1098 " // Callback for when the date is changed.\n",
942 " // Callback for when the date is changed.\n",
1099 " handle_date_change: function(event) {\n",
943 " handle_date_change: function(event) {\n",
1100 " this.model.set('value', this.$date.val());\n",
944 " this.model.set('value', this.$date.val());\n",
945 " this.touch();\n",
1101 " },\n",
946 " },\n",
1102 " \n",
1103 " });\n",
947 " });\n",
1104 " \n",
948 " \n",
1105 " // Register the DatePickerView with the widget manager.\n",
949 " // Register the DatePickerView with the widget manager.\n",
1106 " IPython.widget_manager.register_widget_view('DatePickerView', DatePickerView);\n",
950 " WidgetManager.register_widget_view('DatePickerView', DatePickerView);\n",
1107 "});"
951 "});"
1108 ],
952 ],
1109 "metadata": {},
953 "metadata": {},
1110 "output_type": "display_data",
954 "output_type": "display_data",
1111 "text": [
955 "text": [
1112 "<IPython.core.display.Javascript at 0x10a274a10>"
956 "<IPython.core.display.Javascript at 0x1efe210>"
1113 ]
957 ]
1114 }
958 }
1115 ],
959 ],
1116 "prompt_number": 53
960 "prompt_number": 40
1117 },
961 },
1118 {
962 {
1119 "cell_type": "heading",
963 "cell_type": "heading",
@@ -1135,40 +979,23 b''
1135 "collapsed": false,
979 "collapsed": false,
1136 "input": [
980 "input": [
1137 "# Add some additional widgets for aesthetic purpose\n",
981 "# Add some additional widgets for aesthetic purpose\n",
1138 "display(widgets.StringWidget(description=\"First:\"))\n",
982 "display(widgets.TextBoxWidget(description=\"First:\"))\n",
1139 "display(widgets.StringWidget(description=\"Last:\"))\n",
983 "display(widgets.TextBoxWidget(description=\"Last:\"))\n",
1140 "\n",
984 "\n",
1141 "my_widget = DateWidget(description=\"DOB:\")\n",
985 "my_widget = DateWidget()\n",
1142 "display(my_widget)"
986 "display(my_widget)\n",
1143 ],
987 "my_widget.description=\"DOB:\""
1144 "language": "python",
1145 "metadata": {},
1146 "outputs": [],
1147 "prompt_number": 43
1148 },
1149 {
1150 "cell_type": "markdown",
1151 "metadata": {},
1152 "source": [
1153 "Since the date widget uses `value` and `description`, we can also display its value using a `TextBoxView`. The allows us to look at the raw date value being passed to and from the back-end and front-end."
1154 ]
1155 },
1156 {
1157 "cell_type": "code",
1158 "collapsed": false,
1159 "input": [
1160 "display(my_widget, view_name=\"TextBoxView\")"
1161 ],
988 ],
1162 "language": "python",
989 "language": "python",
1163 "metadata": {},
990 "metadata": {},
1164 "outputs": [],
991 "outputs": [],
1165 "prompt_number": 44
992 "prompt_number": 46
1166 },
993 },
1167 {
994 {
1168 "cell_type": "markdown",
995 "cell_type": "markdown",
1169 "metadata": {},
996 "metadata": {},
1170 "source": [
997 "source": [
1171 "Now we will try to create a widget that only accepts dates in the year 2013. We render the widget without a description to verify that it can still render without a label."
998 "Now we will try to create a widget that only accepts dates in the year 2014. We render the widget without a description to verify that it can still render without a label."
1172 ]
999 ]
1173 },
1000 },
1174 {
1001 {
@@ -1179,25 +1006,25 b''
1179 "display(my_widget)\n",
1006 "display(my_widget)\n",
1180 "\n",
1007 "\n",
1181 "def validate_date(date):\n",
1008 "def validate_date(date):\n",
1182 " return not date is None and date.year == 2013\n",
1009 " return not date is None and date.year == 2014\n",
1183 "my_widget.on_validate(validate_date)"
1010 "my_widget.validation.register_callback(validate_date)"
1184 ],
1011 ],
1185 "language": "python",
1012 "language": "python",
1186 "metadata": {},
1013 "metadata": {},
1187 "outputs": [],
1014 "outputs": [],
1188 "prompt_number": 57
1015 "prompt_number": 47
1189 },
1016 },
1190 {
1017 {
1191 "cell_type": "code",
1018 "cell_type": "code",
1192 "collapsed": false,
1019 "collapsed": false,
1193 "input": [
1020 "input": [
1194 "# Try setting a valid date\n",
1021 "# Try setting a valid date\n",
1195 "my_widget.value = \"December 2, 2013\""
1022 "my_widget.value = \"December 2, 2014\""
1196 ],
1023 ],
1197 "language": "python",
1024 "language": "python",
1198 "metadata": {},
1025 "metadata": {},
1199 "outputs": [],
1026 "outputs": [],
1200 "prompt_number": 46
1027 "prompt_number": 48
1201 },
1028 },
1202 {
1029 {
1203 "cell_type": "code",
1030 "cell_type": "code",
@@ -1209,7 +1036,7 b''
1209 "language": "python",
1036 "language": "python",
1210 "metadata": {},
1037 "metadata": {},
1211 "outputs": [],
1038 "outputs": [],
1212 "prompt_number": 48
1039 "prompt_number": 49
1213 },
1040 },
1214 {
1041 {
1215 "cell_type": "code",
1042 "cell_type": "code",
@@ -1223,21 +1050,13 b''
1223 {
1050 {
1224 "metadata": {},
1051 "metadata": {},
1225 "output_type": "pyout",
1052 "output_type": "pyout",
1226 "prompt_number": 58,
1053 "prompt_number": 50,
1227 "text": [
1054 "text": [
1228 "u''"
1055 "u'2014-12-02'"
1229 ]
1056 ]
1230 }
1057 }
1231 ],
1058 ],
1232 "prompt_number": 58
1059 "prompt_number": 50
1233 },
1234 {
1235 "cell_type": "code",
1236 "collapsed": false,
1237 "input": [],
1238 "language": "python",
1239 "metadata": {},
1240 "outputs": []
1241 }
1060 }
1242 ],
1061 ],
1243 "metadata": {}
1062 "metadata": {}
General Comments 0
You need to be logged in to leave comments. Login now