| OLD | NEW |
| 1 --- | 1 --- |
| 2 layout: default | 2 layout: default |
| 3 title: "Get Input from a Form" | 3 title: "Get Input from a Form" |
| 4 description: "Using HTML forms and input elements to send data to a server" | 4 description: "Using HTML forms and input elements to send data to a server" |
| 5 has-permalinks: true | 5 has-permalinks: true |
| 6 tutorial: | 6 tutorial: |
| 7 id: forms | 7 id: forms |
| 8 next: indexeddb/ | 8 next: indexeddb/ |
| 9 next-title: "Use IndexedDB" | 9 next-title: "Use IndexedDB" |
| 10 prev: fetchdata/ | 10 prev: fetchdata/ |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 | 62 |
| 63 The main example in this tutorial contains a client and a server. | 63 The main example in this tutorial contains a client and a server. |
| 64 The client uses Polymer to present its user interface | 64 The client uses Polymer to present its user interface |
| 65 (a form with many kinds of input elements), | 65 (a form with many kinds of input elements), |
| 66 and keep the interface in sync with Dart data. | 66 and keep the interface in sync with Dart data. |
| 67 The client and server communicate using | 67 The client and server communicate using |
| 68 several classes from the core Dart library, | 68 several classes from the core Dart library, |
| 69 including streams, Futures, HttpRequest, and so on. | 69 including streams, Futures, HttpRequest, and so on. |
| 70 The server uses CORS headers to allow cross-origin requests. | 70 The server uses CORS headers to allow cross-origin requests. |
| 71 | 71 |
| 72 <aside class="alert alert-info" markdown="1"> |
| 73 <strong>Note:</strong> |
| 74 This tutorial assumes that you have read |
| 75 [Define a Custom Elment](/docs/tutorials/polymer-intro/) |
| 76 and [Fetch Data Dynamically](/docs/tutorials/fetchdata/) |
| 77 and are familiar with Polymer, JSON, and HttpRequest. |
| 78 </aside> |
| 79 |
| 80 |
| 72 * [About forms, generally](#about-forms) | 81 * [About forms, generally](#about-forms) |
| 73 * [About the slambook example, specifically](#about-the-slambook-example) | 82 * [About the slambook example, specifically](#about-the-slambook-example) |
| 74 * [Submitting a form](#submitting-a-form) | 83 * [Submitting a form](#submitting-a-form) |
| 75 * [Resetting a form](#resetting-a-form) | 84 * [Resetting a form](#resetting-a-form) |
| 76 * [Creating a server and listening on a port](#creating-a-server) | 85 * [Creating a server and listening on a port](#creating-a-server) |
| 77 * [Handling OPTIONS requests](#handling-options-requests) | 86 * [Handling OPTIONS requests](#handling-options-requests) |
| 78 * [Setting CORS headers](#setting-cors-headers) | 87 * [Setting CORS headers](#setting-cors-headers) |
| 79 * [Handling POST requests](#handling-post-requests) | 88 * [Handling POST requests](#handling-post-requests) |
| 80 * [Recipe for client-server web apps](#recipe) | 89 * [Recipe for client-server web apps](#recipe) |
| 81 * [Binding data to different kinds of inputs](#binding-data) | 90 * [Two-way data binding using Polymer](#binding-data) |
| 82 * [Other resources](#other-resources) | 91 * [Other resources](#other-resources) |
| 92 * [What next?](#what-next) |
| 83 | 93 |
| 84 ##About forms, generally {#about-forms} | 94 ##About forms, generally {#about-forms} |
| 85 | 95 |
| 86 A form has an _action_, which is a URL to which to send the form data, | 96 A form has an _action_, which is a URL to which to send the form data, |
| 87 and a _method_, which indicates how the form data is to be sent. | 97 and a _method_, which indicates how the form data is to be sent. |
| 88 The action and the method can be specified declaratively within HTML, | 98 The action and the method can be specified declaratively within HTML, |
| 89 or for more complex situations or for more control, | 99 or for more complex situations or for more control, |
| 90 you can write Dart code and use Dart libraries to perform the action | 100 you can write Dart code and use Dart libraries to perform the action |
| 91 programmatically. | 101 programmatically. |
| 92 | 102 |
| 93 Let's begin with a basic, HTML-only form to learn a little bit about | 103 Let's begin with a basic, HTML-only form to learn a little bit about |
| 94 action, method, input elements, and the default behavior of forms. | 104 action, method, input elements, and the default behavior of forms. |
| 95 The search_form app running below provides a useful form that | 105 The form below uses Google to search the website |
| 96 you can add to your website pages. | 106 specified in the <form> tag |
| 97 It uses Google to search the specified website | 107 if the checkbox is selected |
| 98 if the checkbox is selected, | 108 (or the web if it is not), |
| 99 or the web if it is not, | |
| 100 for the text entered by the user. | 109 for the text entered by the user. |
| 101 In this example, | 110 In this example, |
| 102 called `search_form`, | 111 called `search_form`, |
| 103 the default is to search | 112 the default is to search |
| 104 [dartlang.org](http://www.dartlang.org) | 113 [dartlang.org](http://www.dartlang.org) |
| 105 for "Cookbook", | 114 for "Cookbook", |
| 106 another useful resource for learning about Dart. | 115 a useful resource for learning about Dart. |
| 107 | 116 |
| 108 <iframe class="running-app-frame" | 117 <iframe class="running-app-frame" |
| 109 style="height:100px;width:500px;" | 118 style="height:100px;width:500px;" |
| 110 src="examples/search_form/web/search_form.html"> | 119 src="examples/search_form/web/search_form.html"> |
| 111 </iframe> | 120 </iframe> |
| 112 | 121 |
| 113 The source code for this example is available on github: | 122 The source code for this example is available on github: |
| 114 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/for
ms/search_form" | 123 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/for
ms/search_form" |
| 115 target="_blank">search_form</a>. | 124 target="_blank">search_form</a>. |
| 116 | 125 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 listens on port 4040 on the local host | 210 listens on port 4040 on the local host |
| 202 and handles POST and OPTIONS requests | 211 and handles POST and OPTIONS requests |
| 203 by printing a message and sending a confirmation to the client. | 212 by printing a message and sending a confirmation to the client. |
| 204 The server uses CORS headers to allow requests from applications | 213 The server uses CORS headers to allow requests from applications |
| 205 running from a different origin. | 214 running from a different origin. |
| 206 | 215 |
| 207 * Second, | 216 * Second, |
| 208 the client program, | 217 the client program, |
| 209 called `slambook`, | 218 called `slambook`, |
| 210 provides a form into which users can enter some information. | 219 provides a form into which users can enter some information. |
| 211 It uses Polymer data binding to bind the input data to Dart variables. | 220 It uses Polymer two-way data binding to bind the input data to Dart variables. |
| 212 When the user clicks the submit button, | 221 When the user clicks the submit button, |
| 213 the Dart code formats the data into a JSON string, | 222 the Dart code formats the data into a JSON string, |
| 214 sends it to slambookserver using an OPTIONS request to | 223 sends an OPTIONS request to get permission from the server, |
| 215 get access first and then a POST request to send the data. | 224 and then a POST request to send the data. |
| 216 When the response from the server is ready, | 225 When the response from the server is ready, |
| 217 the client displays it. | 226 the client displays it. |
| 218 | 227 |
| 219 The following diagram shows the flow of communication between | 228 The following diagram shows the flow of communication between |
| 220 the server and the client in this example. | 229 the server and the client in this example. |
| 221 <hr> | 230 <hr> |
| 222 | 231 |
| 223  | 232  |
| 224 | 233 |
| 225 <hr> | 234 <hr> |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 * Using Polymer to bind the form data to variables in the Dart program | 286 * Using Polymer to bind the form data to variables in the Dart program |
| 278 | 287 |
| 279 On the server side, the sections cover | 288 On the server side, the sections cover |
| 280 | 289 |
| 281 * CORS headers | 290 * CORS headers |
| 282 * Handling OPTIONS requests | 291 * Handling OPTIONS requests |
| 283 * Handling POST requests | 292 * Handling POST requests |
| 284 | 293 |
| 285 ##Submitting a form | 294 ##Submitting a form |
| 286 | 295 |
| 287 Let's first take a look at how that data is submitted to the server. | 296 Let's first take a look at how the data is submitted to the server. |
| 288 | 297 |
| 289 Recall that the search_form example relies on the `action` and | 298 Recall that the search_form example relies on the `action` and |
| 290 `method` attributes to set the destination and method for the form request. | 299 `method` attributes to set the destination and method for the form request. |
| 291 Recall also that the search_form example relies | 300 Recall also that the search_form example relies |
| 292 on the automatic behavior of the special submit button. | 301 on the automatic behavior of the special submit button. |
| 293 The slambook example, | 302 The slambook example, |
| 294 on the other hand, | 303 on the other hand, |
| 295 takes explicit control of the form submission process. | 304 takes explicit control of the form submission process. |
| 296 | 305 |
| 297 * First, the form specifies no action or method. | 306 * First, the form specifies no action or method. |
| 298 * Second, the submit button has a Dart mouse click handler. | 307 * Second, the submit button has a Dart mouse click handler. |
| 299 * Third, the mouse click handler prevents | 308 * Third, the mouse click handler prevents |
| 300 the automatic behavior of the submit button. | 309 the automatic behavior of the submit button. |
| 301 * Finally, the form submits the data to the server | 310 * Finally, the form submits the data to the server |
| 302 with help from the Dart libraries. | 311 with help from the Dart libraries. |
| 303 | 312 |
| 304 The form in the slambook example is | 313 The form in the slambook example is |
| 305 a custom element called `x-slambook-form` | 314 a custom element called `tute-slambook-form` |
| 306 that's instantiated with this HTML code: | 315 that's instantiated with this HTML code: |
| 307 | 316 |
| 308 {% prettify html %} | 317 {% prettify html %} |
| 309 <div class="container"> | 318 <div class="container"> |
| 310 <form is="x-slambook-form" id="slambookform"></form> | 319 <form is="tute-slambook-form" id="slambookform"></form> |
| 311 </div> | 320 </div> |
| 312 {% endprettify %} | 321 {% endprettify %} |
| 313 | 322 |
| 314 Note the absence of either an `action` or a `method` attribute. | 323 Note the absence of either an `action` or a `method` attribute. |
| 315 Instead, the behavior for the submit button is coded in Dart. | 324 Instead, the behavior for the submit button is coded in a Dart |
| 325 mouse click handler. |
| 316 Below is the HTML code that creates the submit button | 326 Below is the HTML code that creates the submit button |
| 317 and binds it to a Dart mouse click handler. | 327 and binds it to a Dart mouse click handler. |
| 318 | 328 |
| 319 {% prettify html %} | 329 {% prettify html %} |
| 320 <div class="submitarea"> | 330 <div class="submitarea"> |
| 321 <input type="submit" value="Submit" on-click="submitForm($event)"> | 331 <input type="submit" value="Submit" on-click="submitForm($event)"> |
| 322 ... | 332 ... |
| 323 </div> | 333 </div> |
| 324 {% endprettify %} | 334 {% endprettify %} |
| 325 | 335 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 // Status is 0...most likely the server isn't running. | 434 // Status is 0...most likely the server isn't running. |
| 425 serverResponse = 'No server'; | 435 serverResponse = 'No server'; |
| 426 } | 436 } |
| 427 } | 437 } |
| 428 {% endprettify %} | 438 {% endprettify %} |
| 429 | 439 |
| 430 First the code checks whether the request is complete and successful. | 440 First the code checks whether the request is complete and successful. |
| 431 If it is, the code puts the server's response in a string, | 441 If it is, the code puts the server's response in a string, |
| 432 called `serverResponse`, which is bound to the value of a textarea | 442 called `serverResponse`, which is bound to the value of a textarea |
| 433 in the slambook app's UI. | 443 in the slambook app's UI. |
| 434 When the string changes, the UI is automatically updated. | 444 When the string changes, the UI is automatically updated, |
| 445 and the message is displayed for the user. |
| 435 | 446 |
| 436 If the request is complete but unsuccessful, | 447 If the request is complete but unsuccessful, |
| 437 the program sets `serverResponse` to an error message, | 448 the program sets `serverResponse` to an error message, |
| 438 thus displaying it to the user. | 449 thus displaying it to the user. |
| 439 | 450 |
| 440 ##Resetting a form | 451 ##Resetting a form |
| 441 | 452 |
| 442 The reset button is a special input type that, by default, | 453 The reset button is a special HTML input type that, by default, |
| 443 clears the values of all inputs within the form. | 454 clears the values of all inputs within the form. |
| 444 Currently, | 455 Instead, we want the button to reset the values in the form |
| 445 this automatic behavior clears the input elements | 456 to their initial value. |
| 446 as expected, | |
| 447 but any bound Dart values do not get updated. | |
| 448 | |
| 449 So, the mouse click handler for the reset button | 457 So, the mouse click handler for the reset button |
| 450 needs to suppress the automatic behavior | 458 needs to suppress the automatic behavior |
| 451 and reset the form with neutral data explicitly. | 459 and reset the form with neutral data explicitly. |
| 452 | 460 |
| 453 {% prettify dart %} | 461 {% prettify dart %} |
| 454 void resetForm(Event e) { | 462 void resetForm(Event e) { |
| 455 e.preventDefault(); | 463 e.preventDefault(); |
| 456 favoriteThings['kittens'] = false; | 464 favoriteThings['kittens'] = false; |
| 457 favoriteThings['raindrops'] = false; | 465 favoriteThings['raindrops'] = false; |
| 458 favoriteThings['mittens'] = false; | 466 favoriteThings['mittens'] = false; |
| 459 favoriteThings['kettles'] = false; | 467 favoriteThings['kettles'] = false; |
| 460 | 468 |
| 461 theData['firstName'] = ''; | 469 theData['firstName'] = ''; |
| 462 theData['favoriteQuote'] = ''; | 470 theData['favoriteQuote'] = ''; |
| 463 theData['favoriteColor'] = '#FFFFFF'; | 471 theData['favoriteColor'] = '#FFFFFF'; |
| 464 theData['birthday'] = '2013-01-01'; | 472 theData['birthday'] = '2013-01-01'; |
| 465 theData['volume'] = '0'; | 473 theData['volume'] = '0'; |
| 466 theData['catOrDog'] = 'cat'; | 474 theData['catOrDog'] = 'cat'; |
| 467 theData['music'] = 0; | 475 theData['music'] = 0; |
| 468 theData['zombies'] = false; | 476 theData['zombies'] = false; |
| 469 serverResponse = "Data cleared."; | 477 serverResponse = "Data reset."; |
| 470 } | 478 } |
| 471 {% endprettify %} | 479 {% endprettify %} |
| 472 | 480 |
| 473 ##Creating a server and listening on a port {#creating-a-server} | 481 ##Creating a server and listening on a port {#creating-a-server} |
| 474 | 482 |
| 475 Let's turn our attention now to the server, called `slambookserver`, | 483 Let's turn our attention now to the server, called `slambookserver`, |
| 476 that responds to HTTP requests from the slambook client. | 484 that responds to HTTP requests from the slambook client. |
| 477 The code for the server is based | 485 The code for the server is based |
| 478 on the one in Chris Buckett's article | 486 on the one in Chris Buckett's article |
| 479 <a href="/articles/json-web-service/">Using Dart with JSON Web Services</a>. | 487 <a href="/articles/json-web-service/">Using Dart with JSON Web Services</a>. |
| (...skipping 27 matching lines...) Expand all Loading... |
| 507 | 515 |
| 508 The bind() function returns a Future object, | 516 The bind() function returns a Future object, |
| 509 which is a way to get a value in the future (more about that in a minute). | 517 which is a way to get a value in the future (more about that in a minute). |
| 510 Using then(), | 518 Using then(), |
| 511 the code registers two callback functions on the Future. | 519 the code registers two callback functions on the Future. |
| 512 The first, gotMessage(), is called when the Future returns its value. | 520 The first, gotMessage(), is called when the Future returns its value. |
| 513 The second, `printError`, is called if the binding fails. | 521 The second, `printError`, is called if the binding fails. |
| 514 An error might occur if, for example, | 522 An error might occur if, for example, |
| 515 another program is already listening on the same port. | 523 another program is already listening on the same port. |
| 516 | 524 |
| 517 The code for gotMessage(), shown below, triages the request | 525 The code for gotMessage(), shown below, filters the request |
| 518 and calls other methods to handle each specific kind of request. | 526 and calls other methods to handle each specific kind of request. |
| 519 | 527 |
| 520 {% prettify dart %} | 528 {% prettify dart %} |
| 521 void gotMessage(_server) { | 529 void gotMessage(_server) { |
| 522 _server.listen((HttpRequest request) { | 530 _server.listen((HttpRequest request) { |
| 523 switch (request.method) { | 531 switch (request.method) { |
| 524 case 'POST': | 532 case 'POST': |
| 525 handlePost(request); | 533 handlePost(request); |
| 526 break; | 534 break; |
| 527 case 'OPTIONS': | 535 case 'OPTIONS': |
| 528 handleOptions(request); | 536 handleOptions(request); |
| 529 break; | 537 break; |
| 530 default: defaultHandler(request); | 538 default: defaultHandler(request); |
| 531 } | 539 } |
| 532 }, | 540 }, |
| 533 onError: printError); // Listen failed. | 541 onError: printError); // Listen failed. |
| 534 print('Listening for GET and POST on http://$HOST:$PORT'); | 542 print('Listening for GET and POST on http://$HOST:$PORT'); |
| 535 } | 543 } |
| 536 {% endprettify %} | 544 {% endprettify %} |
| 537 | 545 |
| 538 To handle other types of requests, | 546 To handle other types of requests |
| 539 you could simply add more `case` statements. | 547 such as `GET` requests, |
| 540 For example, `case 'GET'` for HTTP GET requests. | 548 you could simply add more `case` statements, |
| 549 such as `case 'GET'`. |
| 541 | 550 |
| 542 ###About Futures, briefly | 551 ###About Futures, briefly |
| 543 | 552 |
| 544 Let's take a brief look at Futures before we check out the code | 553 Let's take a brief look at Futures before we check out the code |
| 545 for handling OPTIONS and POST requests. | 554 for handling OPTIONS and POST requests. |
| 546 | 555 |
| 547 A | 556 A |
| 548 <a href="https://api.dartlang.org/dart_async/Future.html" | 557 <a href="https://api.dartlang.org/dart_async/Future.html" |
| 549 target="_blank">Future</a> | 558 target="_blank">Future</a> |
| 550 represents a way to get a value sometime in the Future. | 559 represents a way to get a value sometime in the Future. |
| 551 You use Futures to avoid blocking the program | 560 You use Futures to avoid blocking the program |
| 552 while waiting for a value—for example, | 561 while waiting for a value—for example, |
| 553 if the value requires a long time to compute, | 562 if the value requires a long time to compute, |
| 554 or if the value must be read or retrieved using I/O. | 563 or if the value must be read or retrieved using I/O. |
| 555 | 564 |
| 556 When a function that returns a Future is invoked, | 565 When a function that returns a Future is invoked, |
| 557 two things happen: | 566 two things happen: |
| 558 | 567 |
| 559 <ul> | 568 <ul> |
| 560 <li> | 569 <li> |
| 561 The function queues up work to be done | 570 The function queues up work to be done |
| 562 and returns an uncompleted Future object immediately. | 571 and returns an uncompleted Future object immediately. |
| 563 </li> | 572 </li> |
| 564 <li> | 573 <li> |
| 565 Later, when a value is available, | 574 Later, when the value is available, |
| 566 the Future object completes with that value or with an error. | 575 the Future object completes with that value or with an error. |
| 567 </li> | 576 </li> |
| 568 </ul> | 577 </ul> |
| 569 | 578 |
| 570 To get the value that the Future represents, | 579 To get the value that the Future represents, |
| 571 use the then() method to register a callback. | 580 use the then() method to register a callback. |
| 572 When the Future completes, it calls | 581 When the Future completes, it calls |
| 573 the callback function. | 582 the callback function. |
| 574 | 583 |
| 575 In this example, | 584 In this example, |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 and one in dart:io (for servers). | 747 and one in dart:io (for servers). |
| 739 | 748 |
| 740 | Resource | Library | Description | | 749 | Resource | Library | Description | |
| 741 |---|---| | 750 |---|---| |
| 742 | <a href="https://api.dartlang.org/dart_html/HttpRequest.html" target="_blank">
HttpRequest</a> | dart:html | Client-side HTTP request | | 751 | <a href="https://api.dartlang.org/dart_html/HttpRequest.html" target="_blank">
HttpRequest</a> | dart:html | Client-side HTTP request | |
| 743 | <a href="https://api.dartlang.org/dart_io/HttpRequest.html" target="_blank">Ht
tpRequest</a> | dart:io | Server-side HTTP request | | 752 | <a href="https://api.dartlang.org/dart_io/HttpRequest.html" target="_blank">Ht
tpRequest</a> | dart:io | Server-side HTTP request | |
| 744 | <a href="https://api.dartlang.org/dart_io/HttpServer.html" target="_blank">Htt
pServer</a> | dart:io | Server-side object to handle HTTP communication with cli
ents | | 753 | <a href="https://api.dartlang.org/dart_io/HttpServer.html" target="_blank">Htt
pServer</a> | dart:io | Server-side object to handle HTTP communication with cli
ents | |
| 745 | <a href="https://api.dartlang.org/dart_io/HttpResponse.html" target="_blank">H
ttpResponse</a> | dart:io | Server-side object to carry response to client reque
sts | | 754 | <a href="https://api.dartlang.org/dart_io/HttpResponse.html" target="_blank">H
ttpResponse</a> | dart:io | Server-side object to carry response to client reque
sts | |
| 746 | <a href="https://api.dartlang.org/dart_async/Stream.html" target="_blank">Stre
ams</a> | dart:async | A stream of data | | 755 | <a href="https://api.dartlang.org/dart_async/Stream.html" target="_blank">Stre
ams</a> | dart:async | A stream of data | |
| 747 | <a href="https://api.dartlang.org/dart_async/Future.html" target="_blank">Futu
re</a> | dart:async | A way to get a value asynchronously | | 756 | <a href="https://api.dartlang.org/dart_async/Future.html" target="_blank">Futu
re</a> | dart:async | A way to get a value asynchronously | |
| 748 | <a href="https://api.dartlang.org/dart_json.html" target="_blank">stringify()<
/a> | dart:json | How you format an object into a JSON string | | 757 | <a href="https://api.dartlang.org/dart_json.html" target="_blank">stringify()<
/a> | dart:convert | A library with resources for converting an object into a JS
ON string | |
| 749 | <a href="https://api.dartlang.org/polymer.html" target="_blank">Polymer</a> |
Polymer | Custom elements, data binding, templates | | 758 | <a href="https://api.dartlang.org/polymer.html" target="_blank">Polymer</a> |
Polymer | Custom elements, data binding, templates | |
| 750 {: .table} | 759 {: .table} |
| 751 | 760 |
| 752 ##Binding data to different kinds of inputs {#binding-data} | 761 ##Two-way data binding using Polymer {#binding-data} |
| 753 | 762 |
| 754 The slambook sample uses Polymer to | 763 The slambook sample uses Polymer's two-way data binding to |
| 755 bind the values of input elements to Dart variables. | 764 bind the values of input elements to Dart variables. |
| 756 If the user changes the value in an input element, | 765 If the user changes the value in an input element, |
| 757 the bound variable in the Dart code automatically changes. | 766 the bound variable in the Dart code automatically changes. |
| 758 Or if the Dart code changes the value of the bound variable, | 767 Or if the Dart code changes the value of the bound variable, |
| 759 the UI automatically updates. | 768 the UI automatically updates. |
| 760 [Define a Custom Element](/docs/tutorials/polymer-intro/) | 769 [Define a Custom Element](/docs/tutorials/polymer-intro/) |
| 761 provides introductory details | 770 provides introductory details about Polymer and |
| 762 about data binding with Polymer. | 771 about data binding. |
| 763 | 772 |
| 764 With this example, | 773 The example also uses declarative event handler mapping to hook |
| 774 event handler functions to input elements. |
| 775 |
| 776 With the slambook example, |
| 765 you can see two-way data binding used with a variety of input elements, | 777 you can see two-way data binding used with a variety of input elements, |
| 766 including new HTML5 elements. | 778 including new HTML5 elements. |
| 767 This table summarizes the two-way data binding attributes | 779 This table summarizes the two-way data binding attributes |
| 768 you can use with Polymer: | 780 you can use with Polymer: |
| 769 | 781 |
| 770 | Attribute | Dart type | Input element | | 782 | Attribute | Dart type | Input element | |
| 771 |---|---| | 783 |---|---| |
| 772 | bind-value | String | any <br>with special considerations for elements <br> th
at allow multiple selection,<br> such as a group of radio buttons and <select
> elements | | 784 | value | String | any | |
| 773 | bind-selected-index | integer | a <select> element in which only one cho
ice is allowed | | 785 | selectedIndex | integer | a <select> element in which only one choice is
allowed | |
| 774 | bind-checked | bool | individual radio buttons or checkboxes | | 786 | checked | bool | individual radio buttons or checkboxes | |
| 775 {: .table .nowraptable} | 787 {: .table} |
| 776 | 788 |
| 777 ###Using bind-value with any input element | 789 ###Using value with any input element |
| 778 | 790 |
| 779 The `bind-value` attribute works with any input element | 791 The `value` attribute works with any input element |
| 780 and binds the value to a Dart string. | 792 and binds the value to a Dart string. |
| 781 This example uses `bind-value` with a text field, a text area, | 793 This example uses `value` with a text field, a text area, |
| 782 a color picker, a date chooser, and a range element. | 794 a color picker, a date chooser, and a range element. |
| 783 | 795 |
| 784  | 796  |
| 785 | 797 |
| 786 (Note that some surrounding code, | 798 (Note that some surrounding code, |
| 787 such as that for the labels, | 799 such as that for the labels, |
| 788 has been removed for readability.) | 800 has been removed for readability.) |
| 789 | 801 |
| 790 A map called `theData` in the Dart code contains the data for the form. | 802 A map called `theData` in the Dart code contains the data for the form. |
| 791 The code marks the map object with `@observable` and calls `toObservable()` | 803 The code marks the map object with `@observable` and calls `toObservable()` |
| 792 to make the bindings. | 804 to make the bindings. |
| 793 | 805 |
| 794 The map contains a key-value pair for each input element, | 806 The map contains a key-value pair for each input element, |
| 795 where the key is a string. | 807 where the key is a string. |
| 796 The values in the map can be of any type | 808 The values for elements bound with `value` are all strings. |
| 797 but the values for elements bound with `bind-value` are all strings. | |
| 798 The HTML refers to the items in the map | 809 The HTML refers to the items in the map |
| 799 using their Dart names (identifiers). | 810 using their Dart names (identifiers). |
| 800 For example, the value of the color picker is bound to | 811 For example, the value of the color picker is bound to |
| 801 `theData['favoriteColor']`. | 812 `theData['favoriteColor']`. |
| 802 | 813 |
| 814 {% comment %} |
| 803 ####Special case: Using bind-value with a group of radio buttons | 815 ####Special case: Using bind-value with a group of radio buttons |
| 804 | 816 |
| 805 The slambook form contains three radio buttons, | 817 The slambook form contains three radio buttons, |
| 806 which together make a group | 818 which together make a group |
| 807 because they all have the same name, `catOrDog`. | 819 because they all have the same name, `catOrDog`. |
| 808 All of the radio buttons are bound to the same string. | 820 All of the radio buttons are bound to the same string. |
| 809 Because only one radio button in a group can be selected at a time | 821 Because only one radio button in a group can be selected at a time |
| 810 and each radio button has a different value, | 822 and each radio button has a different value, |
| 811 the bound string reflects the value of the entire group. | 823 the bound string reflects the value of the entire group. |
| 812 | 824 |
| 813  | 825  |
| 814 | 826 |
| 815 {% comment %} | |
| 816 ####Special case: Not using bind-value with a multiple select element | 827 ####Special case: Not using bind-value with a multiple select element |
| 817 | 828 |
| 818 By default a <select> element allows | 829 By default a <select> element allows |
| 819 only one option to be selected at a time. | 830 only one option to be selected at a time. |
| 820 For a single selection <select> element, | 831 For a single selection <select> element, |
| 821 use bind-selected-index (explained below) | 832 use bind-selected-index (explained below) |
| 822 to get the index of the selected option. | 833 to get the index of the selected option. |
| 823 If you want to allow the user to select multiple options, | 834 If you want to allow the user to select multiple options, |
| 824 use the `multiple` attribute. | 835 use the `multiple` attribute. |
| 825 | 836 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 that dynamically creates a List object containing the keys | 913 that dynamically creates a List object containing the keys |
| 903 to the selected books. | 914 to the selected books. |
| 904 | 915 |
| 905  | 916  |
| 906 | 917 |
| 907 The `booksselected` getter has an implied dependency on | 918 The `booksselected` getter has an implied dependency on |
| 908 the `books` map, because the getter uses the map. | 919 the `books` map, because the getter uses the map. |
| 909 When `books` changes, the UI updates the unnumbered list of selected books. | 920 When `books` changes, the UI updates the unnumbered list of selected books. |
| 910 {% endcomment %} | 921 {% endcomment %} |
| 911 | 922 |
| 912 ###Using bind-selected-index with a pull-down menu | 923 ###Using selectedIndex with a pull-down menu |
| 913 | 924 |
| 914 A <select> element contains one or more <option> elements, | 925 A <select> element contains one or more <option> elements, |
| 915 only one of which, by default, can be selected at a time. | 926 only one of which, by default, can be selected at a time. |
| 916 A single-select element is usually implemented as a pull-down menu. | 927 A single-select element is usually implemented as a pull-down menu. |
| 917 You can use the `bind-selected-index` attribute | 928 You can use the `selectedIndex` attribute |
| 918 to bind a Dart integer to a pull-down menu. | 929 to bind a Dart integer to a pull-down menu. |
| 919 The integer indicates the index of the selected item. | 930 The integer indicates the index of the selected item. |
| 920 Indices begin at 0. | 931 Indices begin at 0. |
| 921 | 932 |
| 922  | 933  |
| 923 | 934 |
| 924 ###Using bind-checked with checkboxes | 935 ###Using checked with checkboxes |
| 925 | 936 |
| 926 You can use the `bind-checked` attribute | 937 You can use the `checked` attribute |
| 927 to bind a Dart boolean to a single checkbox. | 938 to bind a Dart boolean to a single checkbox. |
| 928 Here each checkbox is bound to a separate boolean value within a map. | 939 Here each checkbox is bound to a separate boolean value within a map. |
| 929 | 940 |
| 930  | 941  |
| 931 | 942 |
| 932 | 943 |
| 933 ##Other resources | 944 ##Other resources |
| 934 | 945 |
| 935 <ul> | 946 <ul> |
| 936 <li> The code that handles the communication between the | 947 <li> The code that handles the communication between the |
| 937 client and server is based on code written and explained | 948 client and server is based on code written and explained |
| 938 by Chris Buckett in | 949 by Chris Buckett in |
| 939 <a href="/articles/json-web-service/">Using Dart with JSON Web Services</
a>. | 950 <a href="/articles/json-web-service/">Using Dart with JSON Web Services</
a>. |
| 940 </li> | 951 </li> |
| 941 <li> Check out | 952 <li> Check out |
| 942 <a href="/docs/cookbook/"> | 953 <a href="/docs/cookbook/"> |
| 943 <i class="icon-food"> </i> Dart Cookbook</a>. | 954 <i class="icon-food"> </i> Dart Cookbook</a>. |
| 944 You'll find many recipes related to topics in this tutorial, | 955 You'll find many recipes related to topics in this tutorial, |
| 945 including JSON and URIs. | 956 including JSON and URIs. |
| 946 </li> | 957 </li> |
| 947 <li> The previous tutorial, | 958 <li> The previous tutorial, |
| 948 <a href="/docs/tutorials/fetchdata/">Fetch Data Dynamically</a>, | 959 <a href="/docs/tutorials/fetchdata/">Fetch Data Dynamically</a>, |
| 949 contains a more basic client program that relies on the server | 960 contains a more basic client program that relies on the server |
| 950 within Dart Editor (port 3030 on localhost), | 961 within Dart Editor (port 3030 on localhost), |
| 951 to serve the contents of a JSON file. | 962 to serve the contents of a JSON file. |
| 952 </li> | 963 </li> |
| 953 </ul> | 964 </ul> |
| 954 | 965 |
| 955 ###What next? | 966 ###What next? |
| 956 | 967 |
| 957 Try our | 968 The next tutorial, |
| 958 <a href="/codelabs/web-ui-writer/index.html" target="_blank"><i class="icon-beak
er"> </i>Codelab</a>. | 969 [Use IndexedDB](/docs/tutorials/indexeddb), |
| 959 In this step-by-step guide, you’ll build a simple, | 970 describes how to save data on the client |
| 960 single-page, modern web app for desktop and mobile. | 971 in the browser's Indexed Database. |
| 961 | 972 |
| 962 {% endcapture %} | 973 {% endcapture %} |
| 963 | 974 |
| 964 {% include tutorial.html %} | 975 {% include tutorial.html %} |
| OLD | NEW |