OLD | NEW |
| (Empty) |
1 --- | |
2 layout: default | |
3 title: "Define a Custom DOM Tag" | |
4 description: "Define a custom DOM element tag with help from the Web UI package" | |
5 has-permalinks: true | |
6 tutorial: | |
7 id: web-components | |
8 next: polymer-intro/ | |
9 next-title: "Polymer" | |
10 prev: templates/ | |
11 prev-title: "Use Templates" | |
12 --- | |
13 | |
14 {% capture whats_the_point %} | |
15 | |
16 * Make your own DOM element tags with the <element> tag. | |
17 * A custom element requires a template and can have a script. | |
18 * Use data binding to connect Dart variables to content. | |
19 * Directly attach event handlers in HTML. | |
20 | |
21 {% endcapture %} | |
22 | |
23 {% capture sample_links %} | |
24 | |
25 <p> | |
26 Get the source code for the samples featured in this target:</p> | |
27 | |
28 <ul> | |
29 <li> | |
30 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web
/target08/drseuss" | |
31 target="_blank">drseuss</a> | |
32 </li> | |
33 <li> | |
34 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web
/target08/convertthis" | |
35 target="_blank">convertthis</a> | |
36 </li> | |
37 </ul> | |
38 | |
39 {% endcapture %} | |
40 | |
41 {% capture content %} | |
42 | |
43 <div class="tute-target-title"> | |
44 <h1>{{page.title}}</h1> | |
45 <h3>Create your own, customized DOM elements.</h3> | |
46 </div> | |
47 | |
48 <hr> | |
49 | |
50 <aside class="alert" style="background-color:Lavender;color:SlateBlue"> | |
51 <font size="24"> | |
52 <i class="icon-bullhorn"> </i> | |
53 </font> | |
54 Web UI is being upgraded to polymer.dart. | |
55 For more information about polymer.dart, | |
56 including tips on porting Web UI apps to polymer.dart | |
57 and the current status of the project, | |
58 check out the <a href="/polymer-dart/" target="_blank">polymer.dart</a> | |
59 home page. | |
60 For polymer.dart versions of the tutorial's Web UI apps, | |
61 check out the tutorial's | |
62 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/" | |
63 target="_blank">code repo</a> on github. | |
64 </aside> | |
65 | |
66 <hr> | |
67 | |
68 Custom elements are one kind of web component | |
69 defined in the Web Components model. | |
70 Using templates and scripts, | |
71 a custom element defines a new DOM tag | |
72 that extends an existing tag. | |
73 This target shows you how to define a custom element | |
74 and how to create an instance of that element. | |
75 Dart's implementation of custom elements is in the | |
76 <a href="https://pub.dartlang.org/packages/web_ui" | |
77 target="blank">Web UI package</a>, | |
78 which is required to run the examples in this target. | |
79 A previous target, | |
80 <a href="/docs/tutorials/web-ui/">Get Started with Web UI</a>, | |
81 shows you how to install the Web UI package. | |
82 | |
83 * [About custom elements](#about-custom-elements) | |
84 * [Connecting the files](#connecting-the-files) | |
85 * [Instantiating a custom element](#instantiating-a-custom-element) | |
86 * [Defining a custom element](#defining-a-custom-element) | |
87 * [Providing a Dart script](#providing-a-dart-script) | |
88 * [Capturing content from the HTML page](#capturing-content-from-the-html-page) | |
89 * [Using two-way data binding](#using-two-way-data-binding) | |
90 * [Handling events](#handling-events) | |
91 * [Other resources](#other-resources) | |
92 | |
93 ##About custom elements | |
94 | |
95 A custom element defines a new DOM tag | |
96 that extends an existing one. | |
97 You define a custom element tag | |
98 by using <element> and | |
99 providing it with a name for the new tag | |
100 and the name of the tag that it extends. | |
101 This code snippet extends the standard HTML <button> tag. | |
102 The name and extends attributes are both required. | |
103 | |
104 {% prettify html %} | |
105 <element name="x-fancy-button" extends="button"> ... </element> | |
106 {% endprettify %} | |
107 | |
108 To create an instance of a custom element, | |
109 use the element name as you would a regular HTML tag. | |
110 For example, to create an instance of x-fancy-button: | |
111 | |
112 {% prettify html %} | |
113 <x-fancy-button> ... </x-fancy-button> | |
114 {% endprettify %} | |
115 | |
116 You can also create a complex, | |
117 reusable element by bundling elements together inside the custom element. | |
118 Running below is an instance of a custom element, called `x-converter`, | |
119 that extends the <div> tag | |
120 and contains several elements within it. | |
121 Everything within the yellow box is part of the x-converter element. | |
122 Try it! Type a number into one of the fields and press return. | |
123 | |
124 <iframe class="running-app-frame" | |
125 style="height:100px;width:400px;" | |
126 src="http://dart-lang.github.io/dart-tutorials-samples/web/target08/drse
uss/web/out/drseuss.html"> | |
127 </iframe> | |
128 | |
129 You can find the complete source code for this sample on github at | |
130 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get08/drseuss" target="_blank">drseuss</a>. | |
131 | |
132 This repository includes the pubspec.yaml and build.dart | |
133 files necessary to install the Web UI package and build the app. | |
134 Refer to | |
135 <a href="/docs/tutorials/web-ui/">Get Started with Web UI</a> | |
136 for instructions. | |
137 | |
138 The two input fields, the two labels, the left- and right-facing arrows, | |
139 and the Dart code that implements the arithmetic calculation | |
140 work in concert to provide a single widget that converts one number to another. | |
141 This custom extension of <div> wraps all | |
142 of the necessary UI elements and their behavior together into a | |
143 reusable, sharable piece of code. | |
144 Using a mash-up of HTML and Dart | |
145 and supporting functionality in the Web UI package, | |
146 x-converter processes change events on both fields, | |
147 converts the value, | |
148 and puts the result in the opposite field. | |
149 | |
150 Instances of this custom element can be configured | |
151 with different labels and conversion ratios. | |
152 This particular instance of x-converter | |
153 maintains a ratio of 1:2 between the left and right numbers. | |
154 | |
155 The remaining sections | |
156 describe the code that creates instances of the x-converter, | |
157 the HTML code that defines the <x-converter> tag, | |
158 and the Dart code that implements the behavior. | |
159 | |
160 ##Connecting the files | |
161 | |
162 The embedded app just below contains | |
163 three x-converter elements, | |
164 each configured with different labels and | |
165 a different ratio. | |
166 Try it! Enter numbers into each of the fields. | |
167 | |
168 <iframe class="running-app-frame" | |
169 style="height:225px;width:400px;" | |
170 src="http://dart-lang.github.io/dart-tutorials-samples/web/target08/conv
ertthis/web/out/convertThis.html"> | |
171 </iframe> | |
172 | |
173 You can find the complete source code for this sample on github at | |
174 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get08/convertthis" target="_blank">convertthis</a>. | |
175 | |
176 This app is implemented with these Dart and HTML files: | |
177 | |
178 | File | Description| | |
179 |---|---| | |
180 | <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/t
arget08/convertthis/web/converter-element.html" target="_blank">converter-elemen
t.html</a> | Defines the UI for the x-converter custom element | | |
181 | <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/t
arget08/convertthis/web/convertercomponent.dart" target="_blank">convertercompon
ent.dart</a> | Defines the behavior of the x-converter custom element | | |
182 | <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/t
arget08/convertthis/web/convertThis.html" target="_blank">convertThis.html</a> |
Creates three different instances of the x-converter | | |
183 | <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/t
arget08/convertthis/web/convertthis.dart" target="_blank">convertthis.dart</a> |
Contains the Dart main() function, which in this program does nothing | | |
184 {: .table} | |
185 | |
186 HTML code in `converter-element.html` | |
187 implements the look of the x-converter custom component. | |
188 Dart code in `convertercomponent.dart` | |
189 implements the behavior. | |
190 To connect the Dart code to the HTML code use the <script> tag | |
191 within the <element> tag that defines the custom element: | |
192 | |
193 {% prettify html %} | |
194 <element name="x-converter" ...> | |
195 ... | |
196 <script type="application/dart" src="convertercomponent.dart"> </script> | |
197 </element> | |
198 {% endprettify %} | |
199 | |
200 The `convertThis.html` file defines the main HTML page | |
201 and uses the x-converter element. | |
202 The main HTML file must include `converter-element.html` to use it. | |
203 You do this by importing the file with the <link> tag | |
204 in the header. | |
205 | |
206 {% prettify html %} | |
207 <html | |
208 <head> | |
209 ... | |
210 <link rel="import" href="converter-element.html"> | |
211 </head> | |
212 ... | |
213 </html> | |
214 {% endprettify %} | |
215 | |
216 This diagram summarizes the relationships between the files: | |
217 | |
218  | |
219 | |
220 ##Instantiating a custom element | |
221 | |
222 To create the three converter elements | |
223 the converter example uses <x-converter>...</x-converter>. | |
224 It's just as easy as creating a new div or an input field. | |
225 **Important:** You _must_ close each custom element, | |
226 using a closing tag such as </x-converter>. | |
227 | |
228  | |
229 | |
230 As with other DOM elements, | |
231 custom elements can have attributes or content, | |
232 some of which might be required. | |
233 x-converter requires a simple ratio to use for the conversion | |
234 and two labels (each with a specific class name). | |
235 | |
236  | |
237 | |
238 The <x-converter> tag expects an attribute called `ratio`, | |
239 which is a template expression containing a number. | |
240 Recall that template expressions, | |
241 written as \{\{_expression_\}\}, | |
242 bind the value of a Dart variable to HTML content. | |
243 In this example, the number within the curly brackets | |
244 is bound to the Dart variable called `ratio`, | |
245 which is a number in the Dart code | |
246 and is used to convert the numbers. | |
247 If you don't provide the ratio, it defaults to 0.5. | |
248 | |
249 x-converter also expects two labels, | |
250 one for the left input field and one for the right. | |
251 The label for the left input field should have the class name `label-one` | |
252 and the right one should be `label-two`. | |
253 The labels have no default value | |
254 and don't appear if they are not provided. | |
255 | |
256 ##Defining a custom element | |
257 | |
258 Define a custom tag using the <element> tag. | |
259 Besides the required attributes `extends` and `name`, | |
260 the element can also have a `constructor` attribute. | |
261 | |
262  | |
263 | |
264 <dl> | |
265 <dt> extends </dt> | |
266 <dd> Identifies the existing DOM element | |
267 on which the custom tag is based. | |
268 You should either extend an element that closely matches your new element, | |
269 or you should extend div or span. | |
270 </dd> | |
271 | |
272 <dt> name </dt> | |
273 <dd> | |
274 Gives a name to the new element; | |
275 use this name as an HTML tag to create an element of this kind. | |
276 In the Web UI implementation, | |
277 custom element names must begin with `x-`. | |
278 </dd> | |
279 | |
280 <dt> constructor </dt> | |
281 <dd> | |
282 Specifies the Dart type associated with the custom element. | |
283 It is necessary when the name of a custom element (minus the x- prefix) | |
284 differs from the name of the Dart class that implements its behavior. | |
285 </dd> | |
286 </dl> | |
287 | |
288 Within the <element> and </element> tags, | |
289 a custom element definition contains two parts: a template and a script. | |
290 | |
291  | |
292 | |
293 <dl> | |
294 <dt> <template> </dt> | |
295 <dd> | |
296 Contains HTML code | |
297 that describes the element's structure—its user interface. | |
298 The template comprises any valid HTML code between | |
299 <template> and </template>. | |
300 The template HTML is rendered when a custom element is instantiated. | |
301 </dd> | |
302 | |
303 <dt> <script> </dt> | |
304 <dd> Specifies a Dart script. | |
305 It contains the Dart class that implements the behavior of the element. | |
306 Though not required, | |
307 most custom elements have an associated script. | |
308 </dd> | |
309 </dl> | |
310 | |
311 ##Providing a Dart script | |
312 | |
313 To specify a script for a custom element, | |
314 use the HTML <script> tag within the element definition. | |
315 Identify it as Dart with the `type="application/dart"` attribute. | |
316 | |
317 The Dart script must contain a class that is a subclass of WebComponent. | |
318 Usually the name of the Dart class | |
319 is the same as the name of the custom element it implements | |
320 (minus the x- prefix). | |
321 | |
322 However, in the x-converter example, | |
323 the names are different: | |
324 the custom element is x-converter | |
325 and the Dart class is ConverterComponent. | |
326 The following diagram shows the connections | |
327 between the HTML and Dart code for the x-converter element. | |
328 | |
329  | |
330 | |
331 1. Associates a Dart script with the custom element | |
332 and provides the name of a Dart source code file. | |
333 1. Declares the Dart type associated with this custom element | |
334 and the constructor to call to instantiate the element. | |
335 Today, this must be a subclass of WebComponent. | |
336 In the future, it will be possible to use a subclass | |
337 of the HTML element declared in the extends attribute. | |
338 If the constructor is not explicitly named, | |
339 it is assumed to be the CamelCase version of the | |
340 name of the custom element minus the `x-` prefix. | |
341 In this example, it would be Converter. | |
342 | |
343 ##Capturing content from the HTML page | |
344 | |
345 Using the <content> tag | |
346 you can embed nodes from the HTML page | |
347 within a custom element. | |
348 The nodes are provided when the custom element is instantiated. | |
349 | |
350 Here is the complete code for the x-converter definition | |
351 alongside the code that creates one instance of it. | |
352 | |
353  | |
354 | |
355 The HTML code within the <template> definition describes | |
356 the child elements of an x-converter. | |
357 The two input fields and the other elements | |
358 are created for each instance of x-converter. | |
359 | |
360 The <content> tag is a placeholder for the content of the created instance
. | |
361 The x-converter example uses the <content> tag twice, | |
362 once for the left-hand label and once for the right-hand label. | |
363 In this example, | |
364 the <content> tag uses a CSS selector to select an element by class name. | |
365 A pair of empty tags, <content> </content>, | |
366 captures all of the instance's children. | |
367 | |
368 ##Using two-way data binding | |
369 | |
370 A <a href="/docs/tutorials/web-ui/">previous target</a> | |
371 described the Web UI package's two-way data binding feature. | |
372 The x-converter element uses two-way data binding | |
373 to connect the value of each input field to a Dart string variable. | |
374 With observables the Web UI's system keeps the value of the bound Dart string | |
375 in sync with the value of the input field. | |
376 | |
377  | |
378 | |
379 ##Handling events | |
380 | |
381 The Web UI package provides a short-hand for | |
382 directly attaching a Dart event handler to an HTML element. | |
383 Each of the two input fields contained by the x-converter custom element | |
384 have an event handler. | |
385 | |
386  | |
387 | |
388 ##Other resources | |
389 | |
390 <ul> | |
391 <li> Check out | |
392 <a href="/docs/cookbook/"> | |
393 <i class="icon-food"> </i> Dart Cookbook</a>. | |
394 You'll find several | |
395 <a href="/docs/cookbook/#web-ui">Web UI recipes</a>. | |
396 </li> | |
397 <li> | |
398 Sigmund Cherem's article, | |
399 <a href="/articles/dart-web-components/" target="_blank">Web UI Package</a>, | |
400 contains several interactive examples on the page | |
401 and the corresponding source code. | |
402 </li> | |
403 <li> | |
404 The Web UI package contains several examples, | |
405 including a version of | |
406 <a href="https://github.com/dart-lang/web-ui/tree/master/example/todomvc" | |
407 target="_blank">TodoMVC</a>. | |
408 </li> | |
409 </ul> | |
410 | |
411 {% endcapture %} | |
412 | |
413 {% include tutorial.html %} | |
OLD | NEW |