| 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 |