##// END OF EJS Templates
Updated examples 3-6
Jonathan Frederic -
Show More
@@ -46,133 +46,38 b''
46 46 "cell_type": "code",
47 47 "collapsed": false,
48 48 "input": [
49 "floatrange = widgets.FloatSliderWidget() # You can set the parent in the constructor,\n",
50 "\n",
51 "string = widgets.TextBocWidget(value='hi')\n",
49 "floatrange = widgets.FloatSliderWidget()\n",
50 "string = widgets.TextBoxWidget(value='hi')\n",
52 51 "container = widgets.ContainerWidget(children=[floatrange, string])\n",
53 52 "\n",
54 53 "display(container) # Displays the `container` and all of it's children."
55 54 ],
56 55 "language": "python",
57 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 57 "outputs": [],
147 "prompt_number": 6
58 "prompt_number": 2
148 59 },
149 60 {
150 61 "cell_type": "markdown",
151 62 "metadata": {},
152 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 68 "cell_type": "code",
158 69 "collapsed": false,
159 70 "input": [
160 "container = widgets.MulticontainerWidget()\n",
71 "container = widgets.ContainerWidget()\n",
161 72 "display(container)\n",
162 73 "\n",
163 "floatrange = widgets.FloatRangeWidget()\n",
164 "floatrange.parent=container\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"
74 "intrange = widgets.IntSliderWidget()\n",
75 "container.children=[intrange]\n"
171 76 ],
172 77 "language": "python",
173 78 "metadata": {},
174 79 "outputs": [],
175 "prompt_number": 6
80 "prompt_number": 3
176 81 },
177 82 {
178 83 "cell_type": "heading",
@@ -186,20 +91,20 b''
186 91 "cell_type": "markdown",
187 92 "metadata": {},
188 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 98 "cell_type": "code",
194 99 "collapsed": false,
195 100 "input": [
196 "string = widgets.StringWidget(value=\"Hello World!\")\n",
197 "display(string, view_name=\"HTMLView\") "
101 "string = widgets.LatexWidget(value=\"Hello World!\")\n",
102 "display(string) "
198 103 ],
199 104 "language": "python",
200 105 "metadata": {},
201 106 "outputs": [],
202 "prompt_number": 7
107 "prompt_number": 4
203 108 },
204 109 {
205 110 "cell_type": "code",
@@ -210,7 +115,7 b''
210 115 "language": "python",
211 116 "metadata": {},
212 117 "outputs": [],
213 "prompt_number": 8
118 "prompt_number": 5
214 119 },
215 120 {
216 121 "cell_type": "code",
@@ -221,7 +126,7 b''
221 126 "language": "python",
222 127 "metadata": {},
223 128 "outputs": [],
224 "prompt_number": 9
129 "prompt_number": 6
225 130 },
226 131 {
227 132 "cell_type": "markdown",
@@ -235,38 +140,20 b''
235 140 "collapsed": false,
236 141 "input": [
237 142 "form = widgets.ContainerWidget()\n",
238 "first = widgets.StringWidget(description=\"First Name:\")\n",
239 "last = widgets.StringWidget(description=\"Last Name:\")\n",
143 "first = widgets.TextBoxWidget(description=\"First Name:\")\n",
144 "last = widgets.TextBoxWidget(description=\"Last Name:\")\n",
240 145 "\n",
241 "student = widgets.BoolWidget(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",
146 "student = widgets.CheckBoxWidget(description=\"Student:\", value=False)\n",
259 147 "school_info = widgets.ContainerWidget(visible=False, children=[\n",
260 " widgets.StringWidget(description=\"School:\"),\n",
261 " widgets.IntRangeWidget(description=\"Grade:\", min=0, max=12, default_view_name='IntTextView')\n",
148 " widgets.TextBoxWidget(description=\"School:\"),\n",
149 " widgets.IntTextWidget(description=\"Grade:\", min=0, max=12)\n",
262 150 " ])\n",
263 151 "\n",
264 "pet = widgets.StringWidget(description=\"Pet's Name:\")\n",
152 "pet = widgets.TextBoxWidget(description=\"Pet's Name:\")\n",
265 153 "form.children = [first, last, student, school_info, pet]\n",
266 154 "display(form)\n",
267 155 "\n",
268 156 "def on_student_toggle(name, value):\n",
269 " print value\n",
270 157 " if value:\n",
271 158 " school_info.visible = True\n",
272 159 " else:\n",
@@ -275,59 +162,8 b''
275 162 ],
276 163 "language": "python",
277 164 "metadata": {},
278 "outputs": [
279 {
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": []
165 "outputs": [],
166 "prompt_number": 7
331 167 }
332 168 ],
333 169 "metadata": {}
@@ -44,7 +44,7 b''
44 44 "cell_type": "code",
45 45 "collapsed": false,
46 46 "input": [
47 "print(widgets.Widget.set_css.__doc__)"
47 "print(widgets.DOMWidget.set_css.__doc__)"
48 48 ],
49 49 "language": "python",
50 50 "metadata": {},
@@ -53,10 +53,11 b''
53 53 "output_type": "stream",
54 54 "stream": "stdout",
55 55 "text": [
56 "Set one or more CSS properties of the widget (shared among all of the\n",
57 " views). This function has two signatures:\n",
58 " - set_css(css_dict, [selector=''])\n",
59 " - set_css(key, value, [selector=''])\n",
56 "Set one or more CSS properties of the widget.\n",
57 "\n",
58 " This function has two signatures:\n",
59 " - set_css(css_dict, selector='')\n",
60 " - set_css(key, value, selector='')\n",
60 61 "\n",
61 62 " Parameters\n",
62 63 " ----------\n",
@@ -67,7 +68,12 b''
67 68 " value\n",
68 69 " CSS value\n",
69 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 77 " \n"
72 78 ]
73 79 }
@@ -85,7 +91,7 b''
85 91 "cell_type": "code",
86 92 "collapsed": false,
87 93 "input": [
88 "print(widgets.Widget.get_css.__doc__)"
94 "print(widgets.DOMWidget.get_css.__doc__)"
89 95 ],
90 96 "language": "python",
91 97 "metadata": {},
@@ -94,9 +100,10 b''
94 100 "output_type": "stream",
95 101 "stream": "stdout",
96 102 "text": [
97 "Get a CSS property of the widget. Note, this function does not\n",
98 " actually request the CSS from the front-end; Only properties that have\n",
99 " been set with set_css can be read.\n",
103 "Get a CSS property of the widget.\n",
104 "\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 107 "\n",
101 108 " Parameters\n",
102 109 " ----------\n",
@@ -121,8 +128,8 b''
121 128 "cell_type": "code",
122 129 "collapsed": false,
123 130 "input": [
124 "label = widgets.StringWidget(default_view_name=\"HTMLView\")\n",
125 "label.value = \"<strong>ALERT: </strong> Hello World!\"\n",
131 "label = widgets.LatexWidget()\n",
132 "label.value = \"$\\\\textbf{ALERT:} Hello World!$\"\n",
126 133 "container = widgets.ContainerWidget(children=[label])\n",
127 134 "\n",
128 135 "# set_css used to set a single CSS attribute.\n",
@@ -158,7 +165,7 b''
158 165 "cell_type": "code",
159 166 "collapsed": false,
160 167 "input": [
161 "print(widgets.Widget.add_class.__doc__)"
168 "print(widgets.DOMWidget.add_class.__doc__)"
162 169 ],
163 170 "language": "python",
164 171 "metadata": {},
@@ -167,13 +174,12 b''
167 174 "output_type": "stream",
168 175 "stream": "stdout",
169 176 "text": [
170 "Add class[es] to a DOM element\n",
177 "Add class[es] to a DOM element.\n",
171 178 "\n",
172 179 " Parameters\n",
173 180 " ----------\n",
174 " class_name: unicode\n",
175 " Class name(s) to add to the DOM element(s). Multiple class names\n",
176 " must be space separated.\n",
181 " class_names: unicode or list\n",
182 " Class name(s) to add to the DOM element(s).\n",
177 183 " selector: unicode (optional)\n",
178 184 " JQuery selector to select the DOM element(s) that the class(es) will\n",
179 185 " be added to.\n",
@@ -199,8 +205,8 b''
199 205 " 'padding': '6px', \n",
200 206 " 'background': 'yellow'}) \n",
201 207 "\n",
202 "label = widgets.StringWidget(default_view_name=\"HTMLView\")\n",
203 "label.value = \"<strong>ALERT: </strong> Hello World!\"\n",
208 "label = widgets.LatexWidget()\n",
209 "label.value = \"$\\\\textbf{ALERT:} Hello World!$\"\n",
204 210 "container.children = [label]\n",
205 211 "display(container)\n",
206 212 "container.add_class('corner-all') # Must be called AFTER display"
@@ -208,7 +214,7 b''
208 214 "language": "python",
209 215 "metadata": {},
210 216 "outputs": [],
211 "prompt_number": 7
217 "prompt_number": 6
212 218 },
213 219 {
214 220 "cell_type": "markdown",
@@ -221,8 +227,8 b''
221 227 "cell_type": "code",
222 228 "collapsed": false,
223 229 "input": [
224 "label = widgets.StringWidget(value = \"<strong>ALERT: </strong> Hello World!\")\n",
225 "display(label, view_name=\"HTMLView\")\n",
230 "label = widgets.LatexWidget(value = \"$\\\\textbf{ALERT:} Hello World!$\")\n",
231 "display(label)\n",
226 232 "\n",
227 233 "# Apply twitter bootstrap alert class to the label.\n",
228 234 "label.add_class(\"alert\")"
@@ -230,7 +236,7 b''
230 236 "language": "python",
231 237 "metadata": {},
232 238 "outputs": [],
233 "prompt_number": 11
239 "prompt_number": 7
234 240 },
235 241 {
236 242 "cell_type": "markdown",
@@ -260,7 +266,7 b''
260 266 "language": "python",
261 267 "metadata": {},
262 268 "outputs": [],
263 "prompt_number": 12
269 "prompt_number": 8
264 270 },
265 271 {
266 272 "cell_type": "markdown",
@@ -273,7 +279,7 b''
273 279 "cell_type": "code",
274 280 "collapsed": false,
275 281 "input": [
276 "print(widgets.Widget.remove_class.__doc__)"
282 "print(widgets.DOMWidget.remove_class.__doc__)"
277 283 ],
278 284 "language": "python",
279 285 "metadata": {},
@@ -282,13 +288,12 b''
282 288 "output_type": "stream",
283 289 "stream": "stdout",
284 290 "text": [
285 "Remove class[es] from a DOM element\n",
291 "Remove class[es] from a DOM element.\n",
286 292 "\n",
287 293 " Parameters\n",
288 294 " ----------\n",
289 " class_name: unicode\n",
290 " Class name(s) to remove from the DOM element(s). Multiple class\n",
291 " names must be space separated.\n",
295 " class_names: unicode or list\n",
296 " Class name(s) to remove from the DOM element(s).\n",
292 297 " selector: unicode (optional)\n",
293 298 " JQuery selector to select the DOM element(s) that the class(es) will\n",
294 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 307 "cell_type": "markdown",
@@ -310,8 +315,8 b''
310 315 "collapsed": false,
311 316 "input": [
312 317 "import time\n",
313 "label = widgets.StringWidget(value = \"<strong>ALERT: </strong> Hello World!\")\n",
314 "display(label, view_name=\"HTMLView\")\n",
318 "label = widgets.LatexWidget(value = \"$\\\\textbf{ALERT:} Hello World!$\")\n",
319 "display(label)\n",
315 320 "\n",
316 321 "# Apply twitter bootstrap alert class to the label.\n",
317 322 "label.add_class(\"alert\")\n",
@@ -327,15 +332,7 b''
327 332 "language": "python",
328 333 "metadata": {},
329 334 "outputs": [],
330 "prompt_number": 14
331 },
332 {
333 "cell_type": "code",
334 "collapsed": false,
335 "input": [],
336 "language": "python",
337 "metadata": {},
338 "outputs": []
335 "prompt_number": 10
339 336 }
340 337 ],
341 338 "metadata": {}
@@ -44,9 +44,9 b''
44 44 "cell_type": "code",
45 45 "collapsed": false,
46 46 "input": [
47 "display(widgets.StringWidget(description=\"a:\"))\n",
48 "display(widgets.StringWidget(description=\"aa:\"))\n",
49 "display(widgets.StringWidget(description=\"aaa:\"))"
47 "display(widgets.TextBoxWidget(description=\"a:\"))\n",
48 "display(widgets.TextBoxWidget(description=\"aa:\"))\n",
49 "display(widgets.TextBoxWidget(description=\"aaa:\"))"
50 50 ],
51 51 "language": "python",
52 52 "metadata": {},
@@ -64,10 +64,10 b''
64 64 "cell_type": "code",
65 65 "collapsed": false,
66 66 "input": [
67 "display(widgets.StringWidget(description=\"a:\"))\n",
68 "display(widgets.StringWidget(description=\"aa:\"))\n",
69 "display(widgets.StringWidget(description=\"aaa:\"))\n",
70 "display(widgets.StringWidget(description=\"aaaaaaaaaaaaaaaaaa:\"))"
67 "display(widgets.TextBoxWidget(description=\"a:\"))\n",
68 "display(widgets.TextBoxWidget(description=\"aa:\"))\n",
69 "display(widgets.TextBoxWidget(description=\"aaa:\"))\n",
70 "display(widgets.TextBoxWidget(description=\"aaaaaaaaaaaaaaaaaa:\"))"
71 71 ],
72 72 "language": "python",
73 73 "metadata": {},
@@ -85,10 +85,10 b''
85 85 "cell_type": "code",
86 86 "collapsed": false,
87 87 "input": [
88 "display(widgets.StringWidget(description=\"a:\"))\n",
89 "display(widgets.StringWidget(description=\"aa:\"))\n",
90 "display(widgets.StringWidget(description=\"aaa:\"))\n",
91 "display(widgets.StringWidget())"
88 "display(widgets.TextBoxWidget(description=\"a:\"))\n",
89 "display(widgets.TextBoxWidget(description=\"aa:\"))\n",
90 "display(widgets.TextBoxWidget(description=\"aaa:\"))\n",
91 "display(widgets.TextBoxWidget())"
92 92 ],
93 93 "language": "python",
94 94 "metadata": {},
@@ -123,7 +123,14 b''
123 123 "}\n",
124 124 "\n",
125 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 134 " container = widgets.ContainerWidget()\n",
128 135 " container.set_css('background', '#999999')\n",
129 136 " display(container)\n",
@@ -132,16 +139,16 b''
132 139 "def fill_container(container):\n",
133 140 " components = []\n",
134 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 143 " components[i].set_css(child_style)\n",
137 144 " container.children = components\n",
138 145 " \n",
139 146 "container = make_container('VBox')\n",
140 "container.vbox()\n",
147 "container.add_class('vbox')\n",
141 148 "fill_container(container)\n",
142 149 "\n",
143 150 "container = make_container('HBox')\n",
144 "container.hbox()\n",
151 "container.add_class('hbox')\n",
145 152 "fill_container(container)\n"
146 153 ],
147 154 "language": "python",
@@ -161,18 +168,18 b''
161 168 "collapsed": false,
162 169 "input": [
163 170 "container = make_container('HBox Pack Start')\n",
164 "container.hbox()\n",
165 "container.pack_start()\n",
171 "container.add_class('hbox')\n",
172 "container.add_class('start')\n",
166 173 "fill_container(container)\n",
167 174 " \n",
168 175 "container = make_container('HBox Pack Center')\n",
169 "container.hbox()\n",
170 "container.pack_center()\n",
176 "container.add_class('hbox')\n",
177 "container.add_class('center')\n",
171 178 "fill_container(container)\n",
172 179 " \n",
173 180 "container = make_container('HBox Pack End')\n",
174 "container.hbox()\n",
175 "container.pack_end()\n",
181 "container.add_class('hbox')\n",
182 "container.add_class('end')\n",
176 183 "fill_container(container)"
177 184 ],
178 185 "language": "python",
@@ -194,47 +201,49 b''
194 201 "def fill_container(container, flexes):\n",
195 202 " components = []\n",
196 203 " for i in range(len(flexes)):\n",
197 " components.append(widgets.ContainerWidget(parent=container))\n",
204 " components.append(widgets.ContainerWidget())\n",
198 205 " components[i].set_css(child_style)\n",
199 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 210 " \n",
211 " for i in range(len(flexes)):\n",
202 212 " if flexes[i] == 0:\n",
203 " components[i].flex0()\n",
213 " components[i].add_class('box-flex0')\n",
204 214 " elif flexes[i] == 1:\n",
205 " components[i].flex1()\n",
215 " components[i].add_class('box-flex1')\n",
206 216 " elif flexes[i] == 2:\n",
207 " components[i].flex2()\n",
208 " container.children = components\n",
217 " components[i].add_class('box-flex2')\n",
209 218 " \n",
210 219 "container = make_container('Different Flex Configurations')\n",
211 "container.hbox()\n",
220 "container.add_class('hbox')\n",
212 221 "fill_container(container, [0, 0, 0])\n",
213 222 " \n",
214 223 "container = make_container('')\n",
215 "container.hbox()\n",
224 "container.add_class('hbox')\n",
216 225 "fill_container(container, [0, 0, 1])\n",
217 226 " \n",
218 227 "container = make_container('')\n",
219 "container.hbox()\n",
228 "container.add_class('hbox')\n",
220 229 "fill_container(container, [0, 1, 1])\n",
221 230 " \n",
222 231 "container = make_container('')\n",
223 "container.hbox()\n",
232 "container.add_class('hbox')\n",
224 233 "fill_container(container, [0, 2, 2])\n",
225 234 " \n",
226 235 "container = make_container('')\n",
227 "container.hbox()\n",
236 "container.add_class('hbox')\n",
228 237 "fill_container(container, [0, 1, 2])\n",
229 238 " \n",
230 239 "container = make_container('')\n",
231 "container.hbox()\n",
240 "container.add_class('hbox')\n",
232 241 "fill_container(container, [1, 1, 2])"
233 242 ],
234 243 "language": "python",
235 244 "metadata": {},
236 245 "outputs": [],
237 "prompt_number": 8
246 "prompt_number": 7
238 247 },
239 248 {
240 249 "cell_type": "markdown",
@@ -250,30 +259,30 b''
250 259 "def fill_container(container):\n",
251 260 " components = []\n",
252 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 263 " components[i].set_css(child_style)\n",
255 264 " components[i].set_css('height', str((i+1) * 50) + 'px')\n",
256 265 " container.children = components\n",
257 266 "\n",
258 267 "container = make_container('HBox Align Start')\n",
259 "container.hbox()\n",
260 "container.align_start()\n",
268 "container.add_class(\"hbox\")\n",
269 "container.add_class(\"align-start\")\n",
261 270 "fill_container(container)\n",
262 271 " \n",
263 272 "container = make_container('HBox Align Center')\n",
264 "container.hbox()\n",
265 "container.align_center()\n",
273 "container.add_class(\"hbox\")\n",
274 "container.add_class(\"align-center\")\n",
266 275 "fill_container(container)\n",
267 276 " \n",
268 277 "container = make_container('HBox Align End')\n",
269 "container.hbox()\n",
270 "container.align_end()\n",
278 "container.add_class(\"hbox\")\n",
279 "container.add_class(\"align-end\")\n",
271 280 "fill_container(container)"
272 281 ],
273 282 "language": "python",
274 283 "metadata": {},
275 284 "outputs": [],
276 "prompt_number": 9
285 "prompt_number": 8
277 286 },
278 287 {
279 288 "cell_type": "markdown",
@@ -287,23 +296,15 b''
287 296 "collapsed": false,
288 297 "input": [
289 298 "container = widgets.ContainerWidget()\n",
290 "container.hbox()\n",
291 "container.children=[widgets.FloatRangeWidget(orientation='vertical', description=str(i+1), value=50.0) \n",
299 "container.children=[widgets.FloatSliderWidget(orientation='vertical', description=str(i+1), value=50.0) \n",
292 300 " for i in range(15)]\n",
293 "display(container)"
301 "display(container)\n",
302 "container.add_class('hbox')"
294 303 ],
295 304 "language": "python",
296 305 "metadata": {},
297 306 "outputs": [],
298 "prompt_number": 11
299 },
300 {
301 "cell_type": "code",
302 "collapsed": false,
303 "input": [],
304 "language": "python",
305 "metadata": {},
306 "outputs": []
307 "prompt_number": 9
307 308 }
308 309 ],
309 310 "metadata": {}
@@ -37,7 +37,7 b''
37 37 "language": "python",
38 38 "metadata": {},
39 39 "outputs": [],
40 "prompt_number": 15
40 "prompt_number": 19
41 41 },
42 42 {
43 43 "cell_type": "markdown",
@@ -56,7 +56,7 b''
56 56 "language": "python",
57 57 "metadata": {},
58 58 "outputs": [],
59 "prompt_number": 16
59 "prompt_number": 20
60 60 },
61 61 {
62 62 "cell_type": "heading",
@@ -101,25 +101,23 b''
101 101 "collapsed": false,
102 102 "input": [
103 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 105 "from IPython.utils.traitlets import Unicode\n",
106 106 "\n",
107 107 "# Define our DateWidget and its target model and default view.\n",
108 "class DateWidget(Widget):\n",
109 " target_name = Unicode('DateWidgetModel')\n",
110 " default_view_name = Unicode('DatePickerView')"
108 "class DateWidget(DOMWidget):\n",
109 " _view_name = Unicode('DatePickerView', sync=True)"
111 110 ],
112 111 "language": "python",
113 112 "metadata": {},
114 113 "outputs": [],
115 "prompt_number": 17
114 "prompt_number": 21
116 115 },
117 116 {
118 117 "cell_type": "markdown",
119 118 "metadata": {},
120 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",
122 "- **default_view_name** is the default Backbone view to display when the user calls `display` to display an instance of 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"
123 121 ]
124 122 },
125 123 {
@@ -134,7 +132,7 b''
134 132 "cell_type": "markdown",
135 133 "metadata": {},
136 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 141 "input": [
144 142 "%%javascript\n",
145 143 "\n",
146 "require([\"notebook/js/widgets/\"], function(){\n",
144 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
147 145 "\n",
148 146 "});"
149 147 ],
@@ -153,66 +151,24 b''
153 151 {
154 152 "javascript": [
155 153 "\n",
156 "require([\"notebook/js/widget\"], function(){\n",
154 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
157 155 "\n",
158 156 "});"
159 157 ],
160 158 "metadata": {},
161 159 "output_type": "display_data",
162 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
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
165 "prompt_number": 22
210 166 },
211 167 {
212 168 "cell_type": "markdown",
213 169 "metadata": {},
214 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 172 "\n",
217 173 "**Final JavaScript code below:**"
218 174 ]
@@ -223,23 +179,15 b''
223 179 "input": [
224 180 "%%javascript\n",
225 181 "\n",
226 "require([\"notebook/js/widgets/base\"], function(){\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",
182 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
231 183 " \n",
232 184 " // Define the DatePickerView\n",
233 " var DatePickerView = IPython.WidgetView.extend({\n",
234 " \n",
235 " render: function(){\n",
236 " this.$el = $('<div />')\n",
237 " .html('Hello World!');\n",
238 " },\n",
185 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
186 " render: function(){ this.$el.text('Hello World!'); },\n",
239 187 " });\n",
240 188 " \n",
241 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 193 "language": "python",
@@ -248,29 +196,21 b''
248 196 {
249 197 "javascript": [
250 198 "\n",
251 "require([\"notebook/js/widgets/base\"], function(){\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",
199 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
256 200 " \n",
257 201 " // Define the DatePickerView\n",
258 " var DatePickerView = IPython.WidgetView.extend({\n",
259 " \n",
260 " render: function(){\n",
261 " this.$el = $('<div />')\n",
262 " .html('Hello World!');\n",
263 " },\n",
202 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
203 " render: function(){ this.$el.text('Hello World!'); },\n",
264 204 " });\n",
265 205 " \n",
266 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 210 "metadata": {},
271 211 "output_type": "display_data",
272 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 235 "cell_type": "code",
296 236 "collapsed": false,
297 237 "input": [
298 "my_widget = DateWidget()\n",
299 "display(my_widget)"
238 "DateWidget()"
300 239 ],
301 240 "language": "python",
302 241 "metadata": {},
@@ -323,7 +262,7 b''
323 262 "cell_type": "markdown",
324 263 "metadata": {},
325 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 270 "collapsed": false,
332 271 "input": [
333 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 274 "from IPython.utils.traitlets import Unicode\n",
336 275 "\n",
337 276 "# Define our DateWidget and its target model and default view.\n",
338 "class DateWidget(Widget):\n",
339 " target_name = Unicode('DateWidgetModel')\n",
340 " default_view_name = Unicode('DatePickerView')\n",
341 " \n",
342 " # Define the custom state properties to sync with the front-end\n",
343 " _keys = ['value']\n",
344 " value = Unicode()"
277 "class DateWidget(DOMWidget):\n",
278 " _view_name = Unicode('DatePickerView', sync=True)\n",
279 " value = Unicode(sync=True)"
345 280 ],
346 281 "language": "python",
347 282 "metadata": {},
@@ -369,28 +304,21 b''
369 304 "input": [
370 305 "%%javascript\n",
371 306 "\n",
372 "require([\"notebook/js/widgets/base\"], function(){\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",
307 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
377 308 " \n",
378 309 " // Define the DatePickerView\n",
379 " var DatePickerView = IPython.WidgetView.extend({\n",
380 " \n",
310 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
381 311 " render: function(){\n",
382 312 " \n",
383 " // Create a div to hold our widget.\n",
384 " this.$el = $('<div />');\n",
385 " \n",
386 313 " // Create the date picker control.\n",
387 314 " this.$date = $('<input />')\n",
388 " .attr('type', 'date');\n",
315 " .attr('type', 'date')\n",
316 " .appendTo(this.$el);\n",
389 317 " },\n",
390 318 " });\n",
391 319 " \n",
392 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 324 "language": "python",
@@ -399,34 +327,27 b''
399 327 {
400 328 "javascript": [
401 329 "\n",
402 "require([\"notebook/js/widgets/base\"], function(){\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",
330 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
407 331 " \n",
408 332 " // Define the DatePickerView\n",
409 " var DatePickerView = IPython.WidgetView.extend({\n",
410 " \n",
333 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
411 334 " render: function(){\n",
412 335 " \n",
413 " // Create a div to hold our widget.\n",
414 " this.$el = $('<div />');\n",
415 " \n",
416 336 " // Create the date picker control.\n",
417 337 " this.$date = $('<input />')\n",
418 " .attr('type', 'date');\n",
338 " .attr('type', 'date')\n",
339 " .appendTo(this.$el);\n",
419 340 " },\n",
420 341 " });\n",
421 342 " \n",
422 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 347 "metadata": {},
427 348 "output_type": "display_data",
428 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 366 "input": [
446 367 "%%javascript\n",
447 368 "\n",
448 "require([\"notebook/js/widgets/base\"], function(){\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",
369 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
453 370 " \n",
454 371 " // Define the DatePickerView\n",
455 " var DatePickerView = IPython.WidgetView.extend({\n",
456 " \n",
372 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
457 373 " render: function(){\n",
458 374 " \n",
459 " // Create a div to hold our widget.\n",
460 " this.$el = $('<div />');\n",
461 " \n",
462 375 " // Create the date picker control.\n",
463 376 " this.$date = $('<input />')\n",
464 " .attr('type', 'date');\n",
377 " .attr('type', 'date')\n",
378 " .appendTo(this.$el);\n",
465 379 " },\n",
466 380 " \n",
467 381 " update: function() {\n",
468 382 " \n",
469 383 " // Set the value of the date control and then call base.\n",
470 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 386 " },\n",
473 387 " });\n",
474 388 " \n",
475 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 393 "language": "python",
@@ -482,41 +396,34 b''
482 396 {
483 397 "javascript": [
484 398 "\n",
485 "require([\"notebook/js/widgets/base\"], function(){\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",
399 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
490 400 " \n",
491 401 " // Define the DatePickerView\n",
492 " var DatePickerView = IPython.WidgetView.extend({\n",
493 " \n",
402 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
494 403 " render: function(){\n",
495 404 " \n",
496 " // Create a div to hold our widget.\n",
497 " this.$el = $('<div />');\n",
498 " \n",
499 405 " // Create the date picker control.\n",
500 406 " this.$date = $('<input />')\n",
501 " .attr('type', 'date');\n",
407 " .attr('type', 'date')\n",
408 " .appendTo(this.$el);\n",
502 409 " },\n",
503 410 " \n",
504 411 " update: function() {\n",
505 412 " \n",
506 413 " // Set the value of the date control and then call base.\n",
507 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 416 " },\n",
510 417 " });\n",
511 418 " \n",
512 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 423 "metadata": {},
517 424 "output_type": "display_data",
518 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 433 "cell_type": "markdown",
527 434 "metadata": {},
528 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",
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",
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",
532 437 "\n",
533 438 "**Final JavaScript code below:**"
534 439 ]
@@ -539,21 +444,13 b''
539 444 "input": [
540 445 "%%javascript\n",
541 446 "\n",
542 "require([\"notebook/js/widgets/base\"], function(){\n",
543 " \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",
447 "\n",
448 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
547 449 " \n",
548 450 " // Define the DatePickerView\n",
549 " var DatePickerView = IPython.WidgetView.extend({\n",
550 " \n",
451 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
551 452 " render: function(){\n",
552 453 " \n",
553 " // Create a div to hold our widget.\n",
554 " this.$el = $('<div />');\n",
555 " this.delegateEvents();\n",
556 " \n",
557 454 " // Create the date picker control.\n",
558 455 " this.$date = $('<input />')\n",
559 456 " .attr('type', 'date')\n",
@@ -564,7 +461,7 b''
564 461 " \n",
565 462 " // Set the value of the date control and then call base.\n",
566 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 465 " },\n",
569 466 " \n",
570 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 470 " // Callback for when the date is changed.\n",
574 471 " handle_date_change: function(event) {\n",
575 472 " this.model.set('value', this.$date.val());\n",
473 " this.touch();\n",
576 474 " },\n",
577 " \n",
578 475 " });\n",
579 476 " \n",
580 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 481 "language": "python",
@@ -587,21 +484,13 b''
587 484 {
588 485 "javascript": [
589 486 "\n",
590 "require([\"notebook/js/widgets/base\"], function(){\n",
591 " \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",
487 "\n",
488 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
595 489 " \n",
596 490 " // Define the DatePickerView\n",
597 " var DatePickerView = IPython.WidgetView.extend({\n",
598 " \n",
491 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
599 492 " render: function(){\n",
600 493 " \n",
601 " // Create a div to hold our widget.\n",
602 " this.$el = $('<div />');\n",
603 " this.delegateEvents();\n",
604 " \n",
605 494 " // Create the date picker control.\n",
606 495 " this.$date = $('<input />')\n",
607 496 " .attr('type', 'date')\n",
@@ -612,7 +501,7 b''
612 501 " \n",
613 502 " // Set the value of the date control and then call base.\n",
614 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 505 " },\n",
617 506 " \n",
618 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 510 " // Callback for when the date is changed.\n",
622 511 " handle_date_change: function(event) {\n",
623 512 " this.model.set('value', this.$date.val());\n",
513 " this.touch();\n",
624 514 " },\n",
625 " \n",
626 515 " });\n",
627 516 " \n",
628 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 521 "metadata": {},
633 522 "output_type": "display_data",
634 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 531 "cell_type": "heading",
@@ -676,7 +565,7 b''
676 565 "cell_type": "code",
677 566 "collapsed": false,
678 567 "input": [
679 "display(my_widget)"
568 "my_widget"
680 569 ],
681 570 "language": "python",
682 571 "metadata": {},
@@ -702,13 +591,13 b''
702 591 {
703 592 "metadata": {},
704 593 "output_type": "pyout",
705 "prompt_number": 37,
594 "prompt_number": 31,
706 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 603 "cell_type": "markdown",
@@ -726,7 +615,7 b''
726 615 "language": "python",
727 616 "metadata": {},
728 617 "outputs": [],
729 "prompt_number": 34
618 "prompt_number": 32
730 619 },
731 620 {
732 621 "cell_type": "heading",
@@ -763,17 +652,13 b''
763 652 "collapsed": false,
764 653 "input": [
765 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 656 "from IPython.utils.traitlets import Unicode\n",
768 657 "\n",
769 658 "# Define our DateWidget and its target model and default view.\n",
770 "class DateWidget(Widget):\n",
771 " target_name = Unicode('DateWidgetModel')\n",
772 " default_view_name = Unicode('DatePickerView')\n",
773 " \n",
774 " # Define the custom state properties to sync with the front-end\n",
775 " _keys = ['value']\n",
776 " value = Unicode()\n",
659 "class DateWidget(DOMWidget):\n",
660 " _view_name = Unicode('DatePickerView', sync=True)\n",
661 " value = Unicode(sync=True)\n",
777 662 " \n",
778 663 " # This function automatically gets called by the traitlet machinery when\n",
779 664 " # value is modified because of this function's name.\n",
@@ -784,7 +669,7 b''
784 669 "language": "python",
785 670 "metadata": {},
786 671 "outputs": [],
787 "prompt_number": 38
672 "prompt_number": 33
788 673 },
789 674 {
790 675 "cell_type": "markdown",
@@ -797,19 +682,17 b''
797 682 "cell_type": "code",
798 683 "collapsed": false,
799 684 "input": [
685 "# Import the dateutil library to parse date strings.\n",
686 "from dateutil import parser\n",
800 687 "\n",
801 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 690 "from IPython.utils.traitlets import Unicode\n",
804 691 "\n",
805 692 "# Define our DateWidget and its target model and default view.\n",
806 "class DateWidget(Widget):\n",
807 " target_name = Unicode('DateWidgetModel')\n",
808 " default_view_name = Unicode('DatePickerView')\n",
809 " \n",
810 " # Define the custom state properties to sync with the front-end\n",
811 " _keys = ['value']\n",
812 " value = Unicode()\n",
693 "class DateWidget(DOMWidget):\n",
694 " _view_name = Unicode('DatePickerView', sync=True)\n",
695 " value = Unicode(sync=True)\n",
813 696 " \n",
814 697 " # This function automatically gets called by the traitlet machinery when\n",
815 698 " # value is modified because of this function's name.\n",
@@ -829,7 +712,7 b''
829 712 "language": "python",
830 713 "metadata": {},
831 714 "outputs": [],
832 "prompt_number": 39
715 "prompt_number": 34
833 716 },
834 717 {
835 718 "cell_type": "markdown",
@@ -846,18 +729,14 b''
846 729 "from dateutil import parser\n",
847 730 "\n",
848 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 733 "from IPython.utils.traitlets import Unicode\n",
851 734 "\n",
852 735 "# Define our DateWidget and its target model and default view.\n",
853 "class DateWidget(Widget):\n",
854 " target_name = Unicode('DateWidgetModel')\n",
855 " default_view_name = Unicode('DatePickerView')\n",
856 " \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",
736 "class DateWidget(DOMWidget):\n",
737 " _view_name = Unicode('DatePickerView', sync=True)\n",
738 " value = Unicode(sync=True)\n",
739 " description = Unicode(sync=True)\n",
861 740 " \n",
862 741 " # This function automatically gets called by the traitlet machinery when\n",
863 742 " # value is modified because of this function's name.\n",
@@ -877,7 +756,7 b''
877 756 "language": "python",
878 757 "metadata": {},
879 758 "outputs": [],
880 "prompt_number": 40
759 "prompt_number": 35
881 760 },
882 761 {
883 762 "cell_type": "markdown",
@@ -896,22 +775,22 b''
896 775 "from dateutil import parser\n",
897 776 "\n",
898 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 779 "from IPython.utils.traitlets import Unicode\n",
901 780 "\n",
902 781 "# Define our DateWidget and its target model and default view.\n",
903 "class DateWidget(Widget):\n",
904 " target_name = Unicode('DateWidgetModel')\n",
905 " default_view_name = Unicode('DatePickerView')\n",
906 " \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",
782 "class DateWidget(DOMWidget):\n",
783 " _view_name = Unicode('DatePickerView', sync=True)\n",
784 " value = Unicode(sync=True)\n",
785 " description = Unicode(sync=True)\n",
911 786 " \n",
912 787 " def __init__(self, **kwargs):\n",
913 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 794 " \n",
916 795 " # This function automatically gets called by the traitlet machinery when\n",
917 796 " # value is modified because of this function's name.\n",
@@ -922,40 +801,23 b''
922 801 " parsed_date = parser.parse(new_value)\n",
923 802 " parsed_date_string = parsed_date.strftime(\"%Y-%m-%d\")\n",
924 803 " except:\n",
925 " parsed_date = None\n",
926 804 " parsed_date_string = ''\n",
927 805 " \n",
928 806 " # Set the parsed date string if the current date string is different.\n",
929 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 810 " self.value = parsed_date_string\n",
932 811 " else:\n",
933 812 " self.value = old_value\n",
934 813 " self.send_state() # The traitlet event won't fire since the value isn't changing.\n",
935 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",
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 " "
815 " # to make sure that the date control date doesn't change."
954 816 ],
955 817 "language": "python",
956 818 "metadata": {},
957 819 "outputs": [],
958 "prompt_number": 41
820 "prompt_number": 45
959 821 },
960 822 {
961 823 "cell_type": "heading",
@@ -980,23 +842,14 b''
980 842 "input": [
981 843 "%%javascript\n",
982 844 "\n",
983 "require([\"notebook/js/widgets/base\"], function(){\n",
984 " \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",
845 "\n",
846 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
988 847 " \n",
989 848 " // Define the DatePickerView\n",
990 " var DatePickerView = IPython.WidgetView.extend({\n",
991 " \n",
849 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
992 850 " render: function(){\n",
993 " \n",
994 " // Create a div to hold our widget.\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",
851 " this.$el.addClass('widget-hbox-single'); /* Apply this class to the widget container to make\n",
852 " it fit with the other built in widgets.*/\n",
1000 853 " // Create a label.\n",
1001 854 " this.$label = $('<div />')\n",
1002 855 " .addClass('widget-hlabel')\n",
@@ -1020,10 +873,10 b''
1020 873 " this.$label.hide();\n",
1021 874 " } else {\n",
1022 875 " this.$label.show();\n",
1023 " this.$label.html(description);\n",
876 " this.$label.text(description);\n",
1024 877 " }\n",
1025 878 " \n",
1026 " return IPython.WidgetView.prototype.update.call(this);\n",
879 " return DatePickerView.__super__.update.apply(this);\n",
1027 880 " },\n",
1028 881 " \n",
1029 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 885 " // Callback for when the date is changed.\n",
1033 886 " handle_date_change: function(event) {\n",
1034 887 " this.model.set('value', this.$date.val());\n",
888 " this.touch();\n",
1035 889 " },\n",
1036 " \n",
1037 890 " });\n",
1038 891 " \n",
1039 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 896 "language": "python",
@@ -1046,23 +899,14 b''
1046 899 {
1047 900 "javascript": [
1048 901 "\n",
1049 "require([\"notebook/js/widgets/base\"], function(){\n",
1050 " \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",
902 "\n",
903 "require([\"notebook/js/widgets/widget\"], function(WidgetManager){\n",
1054 904 " \n",
1055 905 " // Define the DatePickerView\n",
1056 " var DatePickerView = IPython.WidgetView.extend({\n",
1057 " \n",
906 " var DatePickerView = IPython.DOMWidgetView.extend({\n",
1058 907 " render: function(){\n",
1059 " \n",
1060 " // Create a div to hold our widget.\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",
908 " this.$el.addClass('widget-hbox-single'); /* Apply this class to the widget container to make\n",
909 " it fit with the other built in widgets.*/\n",
1066 910 " // Create a label.\n",
1067 911 " this.$label = $('<div />')\n",
1068 912 " .addClass('widget-hlabel')\n",
@@ -1086,10 +930,10 b''
1086 930 " this.$label.hide();\n",
1087 931 " } else {\n",
1088 932 " this.$label.show();\n",
1089 " this.$label.html(description);\n",
933 " this.$label.text(description);\n",
1090 934 " }\n",
1091 935 " \n",
1092 " return IPython.WidgetView.prototype.update.call(this);\n",
936 " return DatePickerView.__super__.update.apply(this);\n",
1093 937 " },\n",
1094 938 " \n",
1095 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 942 " // Callback for when the date is changed.\n",
1099 943 " handle_date_change: function(event) {\n",
1100 944 " this.model.set('value', this.$date.val());\n",
945 " this.touch();\n",
1101 946 " },\n",
1102 " \n",
1103 947 " });\n",
1104 948 " \n",
1105 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 953 "metadata": {},
1110 954 "output_type": "display_data",
1111 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 963 "cell_type": "heading",
@@ -1135,40 +979,23 b''
1135 979 "collapsed": false,
1136 980 "input": [
1137 981 "# Add some additional widgets for aesthetic purpose\n",
1138 "display(widgets.StringWidget(description=\"First:\"))\n",
1139 "display(widgets.StringWidget(description=\"Last:\"))\n",
982 "display(widgets.TextBoxWidget(description=\"First:\"))\n",
983 "display(widgets.TextBoxWidget(description=\"Last:\"))\n",
1140 984 "\n",
1141 "my_widget = DateWidget(description=\"DOB:\")\n",
1142 "display(my_widget)"
1143 ],
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\")"
985 "my_widget = DateWidget()\n",
986 "display(my_widget)\n",
987 "my_widget.description=\"DOB:\""
1161 988 ],
1162 989 "language": "python",
1163 990 "metadata": {},
1164 991 "outputs": [],
1165 "prompt_number": 44
992 "prompt_number": 46
1166 993 },
1167 994 {
1168 995 "cell_type": "markdown",
1169 996 "metadata": {},
1170 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 1006 "display(my_widget)\n",
1180 1007 "\n",
1181 1008 "def validate_date(date):\n",
1182 " return not date is None and date.year == 2013\n",
1183 "my_widget.on_validate(validate_date)"
1009 " return not date is None and date.year == 2014\n",
1010 "my_widget.validation.register_callback(validate_date)"
1184 1011 ],
1185 1012 "language": "python",
1186 1013 "metadata": {},
1187 1014 "outputs": [],
1188 "prompt_number": 57
1015 "prompt_number": 47
1189 1016 },
1190 1017 {
1191 1018 "cell_type": "code",
1192 1019 "collapsed": false,
1193 1020 "input": [
1194 1021 "# Try setting a valid date\n",
1195 "my_widget.value = \"December 2, 2013\""
1022 "my_widget.value = \"December 2, 2014\""
1196 1023 ],
1197 1024 "language": "python",
1198 1025 "metadata": {},
1199 1026 "outputs": [],
1200 "prompt_number": 46
1027 "prompt_number": 48
1201 1028 },
1202 1029 {
1203 1030 "cell_type": "code",
@@ -1209,7 +1036,7 b''
1209 1036 "language": "python",
1210 1037 "metadata": {},
1211 1038 "outputs": [],
1212 "prompt_number": 48
1039 "prompt_number": 49
1213 1040 },
1214 1041 {
1215 1042 "cell_type": "code",
@@ -1223,21 +1050,13 b''
1223 1050 {
1224 1051 "metadata": {},
1225 1052 "output_type": "pyout",
1226 "prompt_number": 58,
1053 "prompt_number": 50,
1227 1054 "text": [
1228 "u''"
1055 "u'2014-12-02'"
1229 1056 ]
1230 1057 }
1231 1058 ],
1232 "prompt_number": 58
1233 },
1234 {
1235 "cell_type": "code",
1236 "collapsed": false,
1237 "input": [],
1238 "language": "python",
1239 "metadata": {},
1240 "outputs": []
1059 "prompt_number": 50
1241 1060 }
1242 1061 ],
1243 1062 "metadata": {}
General Comments 0
You need to be logged in to leave comments. Login now