OLD | NEW |
(Empty) | |
| 1 --- |
| 2 layout: default |
| 3 title: "Try Dart" |
| 4 description: "Write some Dart code. Learn some stuff." |
| 5 has-permalinks: true |
| 6 tutorial: |
| 7 id: trydart |
| 8 js: |
| 9 - url: /js/os-switcher.js |
| 10 defer: true |
| 11 - url: /js/editor-downloads-analytics.js |
| 12 defer: true |
| 13 - url: /js/editor-version.js |
| 14 defer: true |
| 15 --- |
| 16 |
| 17 # {{ page.title }} |
| 18 |
| 19 ## Got an hour? Write a Dart app. |
| 20 |
| 21 In this code lab, |
| 22 you build a pirate badge generator from a skeleton app. |
| 23 |
| 24 <strong>Learn how to build this app!</strong> |
| 25 |
| 26 <iframe class="running-app-frame" |
| 27 style="height:220px;width:530px;" |
| 28 src="examples/piratebadge/piratebadge.html"> |
| 29 </iframe> |
| 30 |
| 31 <hr> |
| 32 |
| 33 ## The Plan |
| 34 |
| 35 * [Set up](#set-up) |
| 36 * [Step one: Look at the code for the skeleton app](#step-one) |
| 37 * [Step two: Add an input field](#step-two) |
| 38 * [Step three: Add a button](#step-three) |
| 39 * [Step four: Generate random names](#step-four) |
| 40 * [Step five: Create a class for pirate names](#step-five) |
| 41 * [Step six: Add radio buttons](#step-six) |
| 42 * [Step seven: Read the names from a JSON file with HttpRequest](#step-seven) |
| 43 |
| 44 <hr> |
| 45 |
| 46 ## Set up {#set-up} |
| 47 |
| 48 ### To do list {#setup-todolist} |
| 49 |
| 50 <ol> |
| 51 <li> |
| 52 If you haven't already done so, |
| 53 get the Dart download. |
| 54 |
| 55 {% include downloads/_dart-editor.html %} |
| 56 |
| 57 The Dart tools |
| 58 work in recent versions of |
| 59 {% include os-choices.html %} |
| 60 |
| 61 <br> <strong>Having trouble?</strong> Go to the [XXX: troubleshooting page]. |
| 62 </li> |
| 63 <li> |
| 64 Start Dart Editor by double clicking its icon |
| 65 <img src="/imgs/Dart_Logo_21.png" |
| 66 width="21" height="21" alt="Dart Editor icon">. |
| 67 </li> |
| 68 <li> |
| 69 <a href="https://github.com/dart-lang/dart-tutorials-samples/archive/master.zip"
> |
| 70 Download |
| 71 </a> |
| 72 the sample code. |
| 73 Unzip the ZIP file. |
| 74 </li> |
| 75 |
| 76 <li markdown="1"> |
| 77 In Dart Editor, |
| 78 open the `piratebadge` directory from the ZIP file |
| 79 with **File>Open Existing Folder...**. |
| 80 </li> |
| 81 </ol> |
| 82 |
| 83 <div class="row"> |
| 84 <div class="span7" markdown="1"> |
| 85 |
| 86  |
| 87 |
| 88 </div> |
| 89 <div class="span5" markdown="1"> |
| 90 |
| 91 <i class="icon-info-sign"> </i> <strong> Information Treasure Trove </strong> |
| 92 |
| 93 * Dart web apps use the public `browser` package to run on a web page. |
| 94 This project has all of the package dependencies set up for you |
| 95 and the packages installed. |
| 96 The packages directory, the `pubspec.yaml`, and `pubspec.lock` files are |
| 97 all related to library dependencies. |
| 98 |
| 99 * Several numbered directories contain the completed code for each step. |
| 100 `1-blankbadge` contains the skeletal version of the app that you begin with. |
| 101 `6-piratebadge_json` contains the final version of the app. |
| 102 |
| 103 * The `piratebadge.css` file |
| 104 provides the CSS styles for all steps of the app. |
| 105 You don't change this file during this code lab. |
| 106 |
| 107 {% comment %} non-breaking space required for bootstrap/markdown bogosity
{% endcomment %} |
| 108 |
| 109 </div> |
| 110 </div> |
| 111 |
| 112 <hr> |
| 113 |
| 114 ##Step one: Look at the code for the skeleton app {#step-one} |
| 115 |
| 116 ### To do list for step one {#step-one-todolist} |
| 117 |
| 118 1. Expand the `1-blankbadge` directory, |
| 119 which contains two files, `piratebadge.html` and `piratebadge.dart`. |
| 120 You edit both of these files in each step of this code lab. |
| 121 |
| 122 2. Open both files by double-clicking the filename in Dart Editor. |
| 123 |
| 124 3. Run the app in Dart Editor by clicking the Run button |
| 125 <img src="images/run.png" width="16" height="16" |
| 126 alt="Run button">. |
| 127 It's just a boilerplate app, so it doesn't do anything. |
| 128 |
| 129 4. Get familiar with the HTML and Dart code. |
| 130 |
| 131 #### piratebadge.html |
| 132 |
| 133 <div class="row"> |
| 134 <div class="span7" markdown="1"> |
| 135 |
| 136 {% prettify html%} |
| 137 <html> |
| 138 <head> |
| 139 <meta charset="utf-8"> |
| 140 <title>Pirate badge</title> |
| 141 <link rel="stylesheet" href="../piratebadge.css"> |
| 142 </head> |
| 143 <body> |
| 144 <h1>Pirate badge</h1> |
| 145 |
| 146 <div class="container"> |
| 147 <div class="entry"> |
| 148 [[highlight]]<span>TO DO: Put the UI widgets here.</span>[[/highlight]] |
| 149 </div> |
| 150 <div class="outer"> |
| 151 <div class="boilerplate"> |
| 152 Arrr! Me name is |
| 153 </div> |
| 154 <div class="name"> |
| 155 [[highlight]]<span id="badgeName"> </span>[[/highlight]] |
| 156 </div> |
| 157 </div> |
| 158 </div> |
| 159 |
| 160 [[highlight]]<script type="application/dart" src="piratebadge.dart"></script
>[[/highlight]] |
| 161 [[highlight]]<script src="packages/browser/dart.js"></script>[[/highlight]] |
| 162 </body> |
| 163 </html> |
| 164 {% endprettify %} |
| 165 |
| 166 </div> |
| 167 <div class="span5" markdown="1"> |
| 168 |
| 169 <strong>What am I looking at?</strong> |
| 170 |
| 171 * During the code lab, |
| 172 all the changes you make to this file are within |
| 173 the <div> element identfied with the class `entry`. |
| 174 |
| 175 * When you give the app some UI widgets in the next step, |
| 176 the <span> element with the ID `badgename` |
| 177 is programmatically updated by Dart |
| 178 based on user input. |
| 179 |
| 180 * The script `piratebadge.dart` provides the main program for the app. |
| 181 |
| 182 * The script `packages/browser/dart.js` is a bootstrap script |
| 183 that takes care of turning on the Dart VM, |
| 184 as well as compatibility with non-Dart browsers. |
| 185 |
| 186 XXX: use fancy code highlighter for hover |
| 187 |
| 188 </div> |
| 189 |
| 190 </div> |
| 191 |
| 192 #### piratebadge.dart |
| 193 |
| 194 <div class="row"> |
| 195 <div class="span7" markdown="1"> |
| 196 |
| 197 {% prettify dart %} |
| 198 [[highlight]]void main() { |
| 199 // Your app starts here. |
| 200 } |
| 201 [[/highlight]] |
| 202 {% endprettify %} |
| 203 |
| 204 </div> |
| 205 <div class="span5" markdown="1"> |
| 206 |
| 207 * This file is included in the HTML file |
| 208 with the <script> tag. |
| 209 |
| 210 * The `main()` function is a top-level function. |
| 211 Dart calls this function when your app starts. |
| 212 |
| 213 {% comment %} non-breaking space required for bootstrap/markdown bogosity
{% endcomment %} |
| 214 </div> |
| 215 |
| 216 </div> |
| 217 |
| 218 <hr> |
| 219 |
| 220 ##Step two: Add an input field {#step-two} |
| 221 |
| 222 [<a href="#step-two-todolist">Go to the <strong>To do list</strong> for step two
.</a>] |
| 223 |
| 224 ### Concepts for step two {#step-two-concepts} |
| 225 |
| 226 In this step, you add an input field to the HTML code |
| 227 so that the user can type in a name to display on the badge. |
| 228 |
| 229 <strong>Try it!</strong> Type in the text field. [XXX: why oh why is this broken
?] |
| 230 |
| 231 <iframe class="running-app-frame" |
| 232 style="height:220px;width:530px;" |
| 233 src="examples/2-inputnamebadge/piratebadge.html"> |
| 234 </iframe> |
| 235 |
| 236 You provide the the input field with a Dart _input event handler_—a |
| 237 function that gets called when the user types a character in the text field. |
| 238 The event handler changes the badge |
| 239 by changing the text of |
| 240 the <span> element with the ID `badgeName`. |
| 241 |
| 242  |
| 243 |
| 244 ### To do list for step two {#step-two-todolist} |
| 245 |
| 246 #### 1. Add the highlighted code to piratebadge.html as shown: |
| 247 |
| 248 <div class="row"> |
| 249 |
| 250 <div class="span7" markdown="1"> |
| 251 {% prettify html %} |
| 252 ... |
| 253 <div class="entry"> |
| 254 [[highlight]]<div> |
| 255 <input type="text" id="inputName" value="Anne"> |
| 256 </div>[[/highlight]] |
| 257 </div> |
| 258 ... |
| 259 {% endprettify %} |
| 260 </div> |
| 261 <div class="span5" markdown="1"> |
| 262 |
| 263 * The ID for the input element is `inputName`. |
| 264 The Dart code gets this element by querying the DOM for this ID. |
| 265 |
| 266 {% comment %} non-breaking space required for bootstrap/markdown bogosity
{% endcomment %} |
| 267 </div> |
| 268 </div> |
| 269 |
| 270 #### 2. Edit piratebadge.dart. |
| 271 |
| 272 Edit the Dart source code so that it contains the code shown below. |
| 273 |
| 274 <div class="row"> |
| 275 <div class="span7" markdown="1"> |
| 276 {% prettify dart %} |
| 277 import 'dart:html'; |
| 278 |
| 279 InputElement inputNameElement; |
| 280 |
| 281 void main() { |
| 282 inputNameElement = query('#inputName'); |
| 283 inputNameElement.onInput.listen(generateBadge); |
| 284 } |
| 285 |
| 286 void generateBadge(Event event) { |
| 287 query('#badgeName').text = inputNameElement.value; |
| 288 } |
| 289 {% endprettify %} |
| 290 |
| 291 </div> |
| 292 <div class="span5" markdown="1"> |
| 293 |
| 294 * The dart:html library provides HTML elements and access to the DOM. |
| 295 |
| 296 * The `query()` function gets an element from the DOM. |
| 297 This program uses an ID to specify which element. |
| 298 |
| 299 * The code registers an input event handler on the input field. |
| 300 Note the use of cascading operators. |
| 301 |
| 302 * The generateBadge function is a top-level function. |
| 303 It is also an event handler based on its signature. |
| 304 |
| 305 * Set the text of the badgeName element using the value of the input field. |
| 306 |
| 307 {% comment %} non-breaking space required for bootstrap/markdown bogosity
{% endcomment %} |
| 308 </div> |
| 309 </div> |
| 310 |
| 311 ##Step three: Add a button {#step-three} |
| 312 |
| 313 ##Step four: Add a check box {#step-four} |
| 314 |
| 315 In this step you add a checkbox to the app. |
| 316 |
| 317 <strong>Try it!</strong> |
| 318 |
| 319 <iframe class="running-app-frame" |
| 320 style="height:220px;width:530px;" |
| 321 src="examples/3-randombadge/piratebadge.html"> |
| 322 </iframe> |
| 323 |
| 324 ### To do list for step three {#step-three-todolist} |
| 325 |
| 326 #### 1. Edit piratebadge.html as shown: |
| 327 |
| 328 <div class="row"> |
| 329 <div class="span7"> |
| 330 |
| 331 {% prettify html %} |
| 332 ... |
| 333 <div class="entry"> |
| 334 <div> |
| 335 <input type="text" id="inputName" value="Anne"> |
| 336 </div> |
| 337 [[highlight]] |
| 338 <div> |
| 339 <input type="checkbox" id="useRandomName"> |
| 340 <label for="useRandomName">Use random name.</label> |
| 341 </div> |
| 342 <div> |
| 343 <button id="generateButton">Generate badge</button> |
| 344 </div> |
| 345 [[/highlight]] |
| 346 </div> |
| 347 ... |
| 348 {% endprettify %} |
| 349 |
| 350 </div> |
| 351 <div class="span5"> |
| 352 Add a checkbox and a button to the HTML code. |
| 353 |
| 354 The checkbox and the button each have an ID so that |
| 355 the Dart code can query the DOM for these elements. |
| 356 </div> |
| 357 </div> |
| 358 |
| 359 #### 2. Add the highlighted code to piratebadge.dart: |
| 360 |
| 361 <div class="row"> |
| 362 <div class="span7"> |
| 363 |
| 364 {% prettify dart %} |
| 365 [[highlight]]import 'dart:math';[[/highlight]] |
| 366 {% endprettify %} |
| 367 |
| 368 </div> |
| 369 <div class="span5"> |
| 370 Import the `dart:math` library, which includes |
| 371 <a href="https://api.dartlang.org/dart_math/Random.html" target="_blank">Random<
/a>, |
| 372 a random number generator. |
| 373 </div> |
| 374 </div> |
| 375 <div class="row"> |
| 376 <div class="span7"> |
| 377 {% prettify %} |
| 378 InputElement inputNameElement; |
| 379 [[highlight]]bool useRandomName = false;[[/highlight]] |
| 380 [[highlight]] |
| 381 List names = [ "Anne", "Bette", "Cate", "Dawn", |
| 382 "Elise", "Faye", "Ginger", "Harriot", |
| 383 "Izzy", "Jane", "Kaye", "Liz", |
| 384 "Maria", "Nell", "Olive", "Pat", |
| 385 "Queenie", "Rae", "Sal", "Tam", |
| 386 "Uma", "Violet", "Wilma", "Xana", "Yvonne", "Zelda"]; |
| 387 [[/highlight]] |
| 388 {% endprettify %} |
| 389 </div> |
| 390 <div class="span5"> |
| 391 Add two top-level variables, a list literal and a boolean. |
| 392 </div> |
| 393 </div> |
| 394 <div class="row"> |
| 395 <div class="span7"> |
| 396 {% prettify dart %} |
| 397 |
| 398 void main() { |
| 399 [[highlight]] |
| 400 query('#generateButton').onClick.listen(generateBadge); |
| 401 query('#useRandomName').onClick.listen(useRandomNameClickHandler); |
| 402 [[/highlight]] |
| 403 inputNameElement = query('#inputName'); |
| 404 inputNameElement.onInput.listen(generateBadge); |
| 405 } |
| 406 {% endprettify %} |
| 407 |
| 408 </div> |
| 409 <div class="span5"> |
| 410 In the `main()` function, |
| 411 register click handlers to the checkbox and the button. |
| 412 Click handlers respond to mouse clicks. |
| 413 </div> |
| 414 </div> |
| 415 <div class="row"> |
| 416 <div class="span7"> |
| 417 |
| 418 {% prettify dart %} |
| 419 [[highlight]] |
| 420 void useRandomNameClickHandler(MouseEvent e) { |
| 421 if ((e.target as CheckboxInputElement).checked) { |
| 422 inputNameElement.disabled = true; |
| 423 useRandomName = true; |
| 424 } else { |
| 425 inputNameElement.disabled = false; |
| 426 useRandomName = false; |
| 427 } |
| 428 } |
| 429 [[/highlight]] |
| 430 {% endprettify %} |
| 431 |
| 432 </div> |
| 433 <div class="span5"> |
| 434 Add the click handler callback function for the checkbox. |
| 435 If the checkbox is selected, |
| 436 the code disables the input field and sets a variable to true. |
| 437 Note the use of `as` |
| 438 </div> |
| 439 </div> |
| 440 <div class="row"> |
| 441 <div class="span7"> |
| 442 |
| 443 {% prettify dart %} |
| 444 void generateBadge(Event event) { |
| 445 [[highlight]] |
| 446 Random indexGenerator = new Random(); |
| 447 if (useRandomName) { |
| 448 query('#badgeName').text = names[indexGenerator.nextInt(names.length)]; |
| 449 } else { |
| 450 query('#badgeName').text = inputNameElement.value; |
| 451 } |
| 452 [[/highlight]] |
| 453 } |
| 454 {% endprettify %} |
| 455 |
| 456 </div> |
| 457 <div class="span5"> |
| 458 Modify the click handler for the button so that |
| 459 if the checkbox is selected it |
| 460 creates a random number generator and uses it to generate an |
| 461 index into the list of names. |
| 462 </div> |
| 463 </div> |
| 464 </div> |
| 465 |
| 466 ### Concepts for step three {#step-three-concepts} |
| 467 |
| 468 [<a href="#step-four">Go to <strong>Step four</strong></a>.] |
| 469 |
| 470 A |
| 471 <a href="https://api.dartlang.org/dart_core/List.html" target="_blank">List</a> |
| 472 is an ordered collection of objects. |
| 473 This is a List literal that contains three strings: |
| 474 |
| 475 {% prettify dart %} |
| 476 List names == [ "one", "two", "three" ]; |
| 477 {% endprettify %} |
| 478 |
| 479 You can access an item in the List by index: |
| 480 |
| 481 {% prettify dart %} |
| 482 names[0]; // "one" |
| 483 {% endprettify %} |
| 484 |
| 485 You can get the length of a list with the `length` property: |
| 486 |
| 487 {% prettify dart %} |
| 488 names.length; // 3 |
| 489 {% endprettify %} |
| 490 |
| 491 <a href="https://api.dartlang.org/dart_math/Random.html" target="_blank">Random<
/a> |
| 492 is random number generator in the `dart:math` library. |
| 493 This code generates an integer between 0 and 9 inclusive: |
| 494 |
| 495 {% prettify dart %} |
| 496 Random indexGenerator = new Random(); |
| 497 indexGenerator.nextInt(10); // A number between 0 and 9, inclusive. |
| 498 {% endprettify %} |
| 499 |
| 500 [XXX:strengthen] The Dart keyword `as` allows you to refer to an object as a spe
cific type. |
| 501 It's similar to casting in other languages. |
| 502 |
| 503 {% prettify dart %} |
| 504 if ((e.target as CheckboxInputElement).checked) { |
| 505 ... |
| 506 {% endprettify %} |
| 507 |
| 508 Another type of event you can listen for: mouse click events. |
| 509 Useful for buttons and checkboxes. |
| 510 |
| 511 ##Step four: Create a class {#step-four} |
| 512 |
| 513 In this step, you change only the Dart code. |
| 514 |
| 515 ### To do list for step four {#step-four-todolist} |
| 516 |
| 517 #### Edit piratebadge.dart as shown: |
| 518 |
| 519 <div class="row"> |
| 520 <div class="span7"> |
| 521 code here |
| 522 </div> |
| 523 <div class="span5"> |
| 524 <strong>What am I looking at?</strong> |
| 525 </div> |
| 526 </div> |
| 527 |
| 528 |
| 529 ### Concepts for step four {#step-four-concepts} |
| 530 |
| 531 Anatomy of a class |
| 532 |
| 533  |
| 534 |
| 535 {% comment %} |
| 536 #### piratebadge.dart |
| 537 |
| 538 <div class="row"> |
| 539 <div class="span7"> |
| 540 </div> |
| 541 <div class="span5"> |
| 542 </div> |
| 543 </div> |
| 544 |
| 545 #### piratebadge.html |
| 546 |
| 547 <div class="row"> |
| 548 <div class="span7"> |
| 549 </div> |
| 550 <div class="span5"> |
| 551 </div> |
| 552 </div> |
| 553 {% endcomment %} |
OLD | NEW |