Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/site/docs/tutorials/forms/index.markdown

Issue 26922002: removing Web UI tutorials, updating remaining 4 to current release, + review pass (Closed) Base URL: https://github.com/dart-lang/dartlang.org.git@master
Patch Set: merge with master Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 &lt;form&gt; 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
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 ![Client-server communication in the slambook example](images/client-server-comm .png) 232 ![Client-server communication in the slambook example](images/client-server-comm .png)
224 233
225 <hr> 234 <hr>
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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&mdash;for example, 561 while waiting for a value&mdash;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
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 &lt;select &gt; elements | 784 | value | String | any |
773 | bind-selected-index | integer | a &lt;select&gt; element in which only one cho ice is allowed | 785 | selectedIndex | integer | a &lt;select&gt; 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 ![Two-way data binding with bind-value and strings](images/bind-value.png) 796 ![Two-way data binding with value and strings](images/bind-value.png)
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 ![bind-value with a group of radio buttons](images/radio-bindings.png) 825 ![bind-value with a group of radio buttons](images/radio-bindings.png)
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 &lt;select&gt; element allows 829 By default a &lt;select&gt; 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 &lt;select&gt; element, 831 For a single selection &lt;select&gt; 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
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 ![Display list of selected option elements](images/multiselect1.png) 916 ![Display list of selected option elements](images/multiselect1.png)
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 &lt;select&gt; element contains one or more &lt;option&gt; elements, 925 A &lt;select&gt; element contains one or more &lt;option&gt; 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 ![bind-selected-index with a single-selection pull-down menu](images/bind-select ed.png) 933 ![The selectedIndex attribute with a single-selection pull-down menu](images/bin d-selected.png)
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 ![bind-checked with individual checkboxes](images/bind-checked.png) 941 ![The checked attribute with individual checkboxes](images/bind-checked.png)
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 %}
OLDNEW
« no previous file with comments | « src/site/docs/tutorials/forms/images/radio-bindings.png ('k') | src/site/docs/tutorials/get-started/index.markdown » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698