| 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/ |
| 11 prev-title: "Fetch Data Dynamically" | 11 prev-title: "Fetch Data Dynamically" |
| 12 --- | 12 --- |
| 13 | 13 |
| 14 {% capture whats_the_point %} | 14 {% capture whats_the_point %} |
| 15 | 15 |
| 16 * Use forms with inputs to gather data from a user. | 16 * Use forms with inputs to gather data from a user. |
| 17 * Send data to the server, declaratively or programmatically. | 17 * Send data to the server, declaratively or programmatically. |
| 18 * Get the response from the server with HttpRequest. | 18 * Get the response from the server with HttpRequest. |
| 19 * Handle communication asynchronously with Futures. | 19 * Handle communication asynchronously with Futures. |
| 20 * Use HttpServer to set up a server to listen on a port and host. | 20 * Use HttpServer to set up a server to listen on a port and host. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 for the text entered by the user. | 117 for the text entered by the user. |
| 118 In this example, | 118 In this example, |
| 119 called `search_form`, | 119 called `search_form`, |
| 120 the default is to search | 120 the default is to search |
| 121 [dartlang.org](http://www.dartlang.org) | 121 [dartlang.org](http://www.dartlang.org) |
| 122 for "Cookbook", | 122 for "Cookbook", |
| 123 another useful resource for learning about Dart. | 123 another useful resource for learning about Dart. |
| 124 | 124 |
| 125 <iframe class="running-app-frame" | 125 <iframe class="running-app-frame" |
| 126 style="height:100px;width:500px;" | 126 style="height:100px;width:500px;" |
| 127 src="http://dart-lang.github.com/dart-tutorials-samples/web/target10/sea
rch_form/web/search_form.html"> | 127 src="http://dart-lang.github.io/dart-tutorials-samples/web/target10/sear
ch_form/web/search_form.html"> |
| 128 </iframe> | 128 </iframe> |
| 129 | 129 |
| 130 The source code for this example is available on github: | 130 The source code for this example is available on github: |
| 131 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get10/search_form" | 131 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get10/search_form" |
| 132 target="_blank">search_form</a>. | 132 target="_blank">search_form</a>. |
| 133 | 133 |
| 134 Here is the HTML code that creates the form: | 134 Here is the HTML code that creates the form: |
| 135 | 135 |
| 136 {% prettify html %} | 136 {% prettify html %} |
| 137 <form action="http://www.google.com/search" | 137 <form action="http://www.google.com/search" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 | 239 |
| 240  | 240  |
| 241 | 241 |
| 242 <hr> | 242 <hr> |
| 243 | 243 |
| 244 **Try it!** | 244 **Try it!** |
| 245 Enter some data and push the **Submit** button. | 245 Enter some data and push the **Submit** button. |
| 246 | 246 |
| 247 <iframe class="running-app-frame" | 247 <iframe class="running-app-frame" |
| 248 style="height:500px;width:525px;" | 248 style="height:500px;width:525px;" |
| 249 src="http://dart-lang.github.com/dart-tutorials-samples/web/target10/sla
mbook/web/out/slambook.html"> | 249 src="http://dart-lang.github.io/dart-tutorials-samples/web/target10/slam
book/web/out/slambook.html"> |
| 250 </iframe> | 250 </iframe> |
| 251 | 251 |
| 252 The complete source code for both the client and the | 252 The complete source code for both the client and the |
| 253 server is available on github: | 253 server is available on github: |
| 254 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get10/slambook" target="_blank">slambook</a> | 254 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get10/slambook" target="_blank">slambook</a> |
| 255 | 255 |
| 256 The request gives you an innocent stare and displays "No server" | 256 The request gives you an innocent stare and displays "No server" |
| 257 because you are not running the server on your machine. | 257 because you are not running the server on your machine. |
| 258 Let's fix that. | 258 Let's fix that. |
| 259 | 259 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 } | 364 } |
| 365 {% endprettify %} | 365 {% endprettify %} |
| 366 | 366 |
| 367 {% comment %} | 367 {% comment %} |
| 368 [xx: mention here that you can intercept and forward, etc] | 368 [xx: mention here that you can intercept and forward, etc] |
| 369 {% endcomment %} | 369 {% endcomment %} |
| 370 | 370 |
| 371 ###Setting up and making the POST request | 371 ###Setting up and making the POST request |
| 372 | 372 |
| 373 Next, the code creates an | 373 Next, the code creates an |
| 374 <a href="http://api.dartlang.org/dart_html/HttpRequest.html" target="_blank">Htt
pRequest</a> | 374 <a href="https://api.dartlang.org/dart_html/HttpRequest.html" target="_blank">Ht
tpRequest</a> |
| 375 object. | 375 object. |
| 376 This code uses `new` to create an HttpRequest object, | 376 This code uses `new` to create an HttpRequest object, |
| 377 which needs to be configured to make a POST request. | 377 which needs to be configured to make a POST request. |
| 378 The HttpRequest class has a convenience function, getString(), | 378 The HttpRequest class has a convenience function, getString(), |
| 379 that you can use to make a basic GET request on a URL. | 379 that you can use to make a basic GET request on a URL. |
| 380 | 380 |
| 381 The next line provides the HttpRequest object with a callback function, | 381 The next line provides the HttpRequest object with a callback function, |
| 382 called `onData`, | 382 called `onData`, |
| 383 that gets invoked when the server responds. | 383 that gets invoked when the server responds. |
| 384 We'll look at the implementation details for onData() later. | 384 We'll look at the implementation details for onData() later. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 For both types of requests, | 502 For both types of requests, |
| 503 the server adds CORS headers to allow access. | 503 the server adds CORS headers to allow access. |
| 504 For POST requests, | 504 For POST requests, |
| 505 the server returns a short confirmation message | 505 the server returns a short confirmation message |
| 506 that includes the JSON data it received in the request. | 506 that includes the JSON data it received in the request. |
| 507 | 507 |
| 508 Let's take a look at the code. | 508 Let's take a look at the code. |
| 509 | 509 |
| 510 Below is the entire main() function for slambookserver. | 510 Below is the entire main() function for slambookserver. |
| 511 Using the | 511 Using the |
| 512 <a href="http://api.dartlang.org/dart_io/HttpServer.html" | 512 <a href="https://api.dartlang.org/dart_io/HttpServer.html" |
| 513 target="_blank">HttpServer</a> | 513 target="_blank">HttpServer</a> |
| 514 class, | 514 class, |
| 515 slambookserver starts listening on port 4040 on the local host | 515 slambookserver starts listening on port 4040 on the local host |
| 516 by calling the top-level bind() function. | 516 by calling the top-level bind() function. |
| 517 | 517 |
| 518 {% prettify dart %} | 518 {% prettify dart %} |
| 519 final HOST = '127.0.0.1'; | 519 final HOST = '127.0.0.1'; |
| 520 final PORT = 4040; | 520 final PORT = 4040; |
| 521 | 521 |
| 522 void main() { | 522 void main() { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 To handle other types of requests, | 557 To handle other types of requests, |
| 558 you could simply add more `case` statements. | 558 you could simply add more `case` statements. |
| 559 For example, `case 'GET'` for HTTP GET requests. | 559 For example, `case 'GET'` for HTTP GET requests. |
| 560 | 560 |
| 561 ###About Futures, briefly | 561 ###About Futures, briefly |
| 562 | 562 |
| 563 Let's take a brief look at Futures before we check out the code | 563 Let's take a brief look at Futures before we check out the code |
| 564 for handling OPTIONS and POST requests. | 564 for handling OPTIONS and POST requests. |
| 565 | 565 |
| 566 A | 566 A |
| 567 <a href="http://api.dartlang.org/dart_async/Future.html" | 567 <a href="https://api.dartlang.org/dart_async/Future.html" |
| 568 target="_blank">Future</a> | 568 target="_blank">Future</a> |
| 569 represents a way to get a value sometime in the Future. | 569 represents a way to get a value sometime in the Future. |
| 570 You use Futures to avoid blocking the program | 570 You use Futures to avoid blocking the program |
| 571 while waiting for a value—for example, | 571 while waiting for a value—for example, |
| 572 if the value requires a long time to compute, | 572 if the value requires a long time to compute, |
| 573 or if the value must be read or retrieved using I/O. | 573 or if the value must be read or retrieved using I/O. |
| 574 | 574 |
| 575 When a function that returns a Future is invoked, | 575 When a function that returns a Future is invoked, |
| 576 two things happen: | 576 two things happen: |
| 577 | 577 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 593 | 593 |
| 594 In this example, | 594 In this example, |
| 595 both the client and server use Futures when sending requests | 595 both the client and server use Futures when sending requests |
| 596 and responses back and forth. | 596 and responses back and forth. |
| 597 Client-server programs should almost always handle communication | 597 Client-server programs should almost always handle communication |
| 598 and other forms of I/O asynchronously with Futures. | 598 and other forms of I/O asynchronously with Futures. |
| 599 | 599 |
| 600 ##Handling OPTIONS requests | 600 ##Handling OPTIONS requests |
| 601 | 601 |
| 602 With help from the | 602 With help from the |
| 603 <a href="http://api.dartlang.org/dart_html/HttpRequest.html" | 603 <a href="https://api.dartlang.org/dart_html/HttpRequest.html" |
| 604 target="_blank">HttpRequest</a> | 604 target="_blank">HttpRequest</a> |
| 605 class, the slambook client makes a POST request | 605 class, the slambook client makes a POST request |
| 606 when the user clicks the submit button. | 606 when the user clicks the submit button. |
| 607 You saw the code for this earlier in this target. | 607 You saw the code for this earlier in this target. |
| 608 | 608 |
| 609 If the client is running from a different origin than the server, | 609 If the client is running from a different origin than the server, |
| 610 which is common in web apps, | 610 which is common in web apps, |
| 611 the POST request is "preflighted". | 611 the POST request is "preflighted". |
| 612 A preflighted request must first send an OPTIONS request | 612 A preflighted request must first send an OPTIONS request |
| 613 to determine if the actual request is allowed. | 613 to determine if the actual request is allowed. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 624 addCorsHeaders(res); | 624 addCorsHeaders(res); |
| 625 print('${req.method}: ${req.uri.path}'); | 625 print('${req.method}: ${req.uri.path}'); |
| 626 res.statusCode = HttpStatus.NO_CONTENT; | 626 res.statusCode = HttpStatus.NO_CONTENT; |
| 627 res.close(); | 627 res.close(); |
| 628 } | 628 } |
| 629 {% endprettify %} | 629 {% endprettify %} |
| 630 | 630 |
| 631 The code is straightforward: | 631 The code is straightforward: |
| 632 | 632 |
| 633 * Get the | 633 * Get the |
| 634 <a href="http://api.dartlang.org/dart_io/HttpResponse.html" | 634 <a href="https://api.dartlang.org/dart_io/HttpResponse.html" |
| 635 target="_blank">HttpResponse</a> | 635 target="_blank">HttpResponse</a> |
| 636 object, | 636 object, |
| 637 which carries the server's response to the client. | 637 which carries the server's response to the client. |
| 638 * Add CORS headers to set access control | 638 * Add CORS headers to set access control |
| 639 * Print a message to the console | 639 * Print a message to the console |
| 640 * Indicate that the response has no content | 640 * Indicate that the response has no content |
| 641 * Close the response, thus sending the response to the client. | 641 * Close the response, thus sending the response to the client. |
| 642 | 642 |
| 643 When the client gets the response, | 643 When the client gets the response, |
| 644 the CORS headers indicate that a POST request would be accepted. | 644 the CORS headers indicate that a POST request would be accepted. |
| 645 | 645 |
| 646 ##Setting CORS headers | 646 ##Setting CORS headers |
| 647 | 647 |
| 648 The server uses the following function | 648 The server uses the following function |
| 649 to add CORS headers to its response to both OPTIONS and POST requests. | 649 to add CORS headers to its response to both OPTIONS and POST requests. |
| 650 The function adds three Access-Control headers to the | 650 The function adds three Access-Control headers to the |
| 651 server's response (contained in an | 651 server's response (contained in an |
| 652 <a href="http://api.dartlang.org/dart_html/HttpRequest.html" | 652 <a href="https://api.dartlang.org/dart_html/HttpRequest.html" |
| 653 target="_blank">HttpResponse</a> | 653 target="_blank">HttpResponse</a> |
| 654 object). | 654 object). |
| 655 | 655 |
| 656 {% prettify dart %} | 656 {% prettify dart %} |
| 657 void addCorsHeaders(HttpResponse res) { | 657 void addCorsHeaders(HttpResponse res) { |
| 658 res.headers.add('Access-Control-Allow-Origin', '*, '); | 658 res.headers.add('Access-Control-Allow-Origin', '*, '); |
| 659 res.headers.add('Access-Control-Allow-Methods', 'POST, OPTIONS'); | 659 res.headers.add('Access-Control-Allow-Methods', 'POST, OPTIONS'); |
| 660 res.headers.add('Access-Control-Allow-Headers', | 660 res.headers.add('Access-Control-Allow-Headers', |
| 661 'Origin, X-Requested-With, Content-Type, Accept'); | 661 'Origin, X-Requested-With, Content-Type, Accept'); |
| 662 } | 662 } |
| 663 {% endprettify %} | 663 {% endprettify %} |
| 664 | 664 |
| 665 Together, | 665 Together, |
| 666 the first two CORS headers allow | 666 the first two CORS headers allow |
| 667 POST and OPTIONS requests from any origin. | 667 POST and OPTIONS requests from any origin. |
| 668 The third specifies | 668 The third specifies |
| 669 the kind of POST and OPTIONS requests the server accepts | 669 the kind of POST and OPTIONS requests the server accepts |
| 670 by specifying the headers that it allows. | 670 by specifying the headers that it allows. |
| 671 | 671 |
| 672 For more information about CORS refer to: | 672 For more information about CORS refer to: |
| 673 | 673 |
| 674 * <a href="http://www.html5rocks.com/en/tutorials/cors/">Using CORS</a> | 674 * <a href="https://www.html5rocks.com/en/tutorials/cors/">Using CORS</a> |
| 675 | 675 |
| 676 ##Handling POST requests | 676 ##Handling POST requests |
| 677 | 677 |
| 678 Here is the function that handles the client's HTTP POST request: | 678 Here is the function that handles the client's HTTP POST request: |
| 679 | 679 |
| 680 {% prettify dart %} | 680 {% prettify dart %} |
| 681 void handlePost(HttpRequest req) { | 681 void handlePost(HttpRequest req) { |
| 682 HttpResponse res = req.response; | 682 HttpResponse res = req.response; |
| 683 print('${req.method}: ${req.uri.path}'); | 683 print('${req.method}: ${req.uri.path}'); |
| 684 | 684 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 * Handle communication asynchronously with Futures. | 751 * Handle communication asynchronously with Futures. |
| 752 * Use streams to write the response data. | 752 * Use streams to write the response data. |
| 753 | 753 |
| 754 These resources, mostly from the core Dart libraries, | 754 These resources, mostly from the core Dart libraries, |
| 755 provide support for writing clients and servers. | 755 provide support for writing clients and servers. |
| 756 Note that there are two HttpRequest classes, one in dart:html (for clients) | 756 Note that there are two HttpRequest classes, one in dart:html (for clients) |
| 757 and one in dart:io (for servers). | 757 and one in dart:io (for servers). |
| 758 | 758 |
| 759 | Resource | Library | Description | | 759 | Resource | Library | Description | |
| 760 |---|---| | 760 |---|---| |
| 761 | <a href="http://api.dartlang.org/dart_html/HttpRequest.html" target="_blank">H
ttpRequest</a> | dart:html | Client-side HTTP request | | 761 | <a href="https://api.dartlang.org/dart_html/HttpRequest.html" target="_blank">
HttpRequest</a> | dart:html | Client-side HTTP request | |
| 762 | <a href="http://api.dartlang.org/dart_io/HttpRequest.html" target="_blank">Htt
pRequest</a> | dart:io | Server-side HTTP request | | 762 | <a href="https://api.dartlang.org/dart_io/HttpRequest.html" target="_blank">Ht
tpRequest</a> | dart:io | Server-side HTTP request | |
| 763 | <a href="http://api.dartlang.org/dart_io/HttpServer.html" target="_blank">Http
Server</a> | dart:io | Server-side object to handle HTTP communication with clie
nts | | 763 | <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 | |
| 764 | <a href="http://api.dartlang.org/dart_io/HttpResponse.html" target="_blank">Ht
tpResponse</a> | dart:io | Server-side object to carry response to client reques
ts | | 764 | <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 | |
| 765 | <a href="http://api.dartlang.org/dart_async/Stream.html" target="_blank">Strea
ms</a> | dart:async | A stream of data | | 765 | <a href="https://api.dartlang.org/dart_async/Stream.html" target="_blank">Stre
ams</a> | dart:async | A stream of data | |
| 766 | <a href="http://api.dartlang.org/dart_async/Future.html" target="_blank">Futur
e</a> | dart:async | A way to get a value asynchronously | | 766 | <a href="https://api.dartlang.org/dart_async/Future.html" target="_blank">Futu
re</a> | dart:async | A way to get a value asynchronously | |
| 767 | <a href="http://api.dartlang.org/dart_json.html" target="_blank">stringify()</
a> | dart:json | How you format an object into a JSON string | | 767 | <a href="https://api.dartlang.org/dart_json.html" target="_blank">stringify()<
/a> | dart:json | How you format an object into a JSON string | |
| 768 | <a href="http://pub.dartlang.org/packages/web_ui" target="_blank">Web UI packa
ge</a> | web_ui | Data binding, templates, and custom elements | | 768 | <a href="https://pub.dartlang.org/packages/web_ui" target="_blank">Web UI pack
age</a> | web_ui | Data binding, templates, and custom elements | |
| 769 {: .table} | 769 {: .table} |
| 770 | 770 |
| 771 ##Binding data to different kinds of inputs {#binding-data} | 771 ##Binding data to different kinds of inputs {#binding-data} |
| 772 | 772 |
| 773 The slambook sample uses the Web UI package to | 773 The slambook sample uses the Web UI package to |
| 774 bind the values of input elements to Dart variables. | 774 bind the values of input elements to Dart variables. |
| 775 If the user changes the value in an input element, | 775 If the user changes the value in an input element, |
| 776 the bound variable in the Dart code automatically changes. | 776 the bound variable in the Dart code automatically changes. |
| 777 Or if the Dart code changes the value of the bound variable, | 777 Or if the Dart code changes the value of the bound variable, |
| 778 the UI automatically updates. | 778 the UI automatically updates. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 `multiselect`. | 854 `multiselect`. |
| 855 | 855 |
| 856 **Try it!** | 856 **Try it!** |
| 857 | 857 |
| 858 * Click to select one option. | 858 * Click to select one option. |
| 859 * Shift-click to select options in series. | 859 * Shift-click to select options in series. |
| 860 * Command-click to make a discontiguous selection. | 860 * Command-click to make a discontiguous selection. |
| 861 | 861 |
| 862 <iframe class="running-app-frame" | 862 <iframe class="running-app-frame" |
| 863 style="height:400px;width:500px;" | 863 style="height:400px;width:500px;" |
| 864 src="http://dart-lang.github.com/dart-tutorials-samples/web/target10/mul
tiselect/web/out/multiselect.html"> | 864 src="http://dart-lang.github.io/dart-tutorials-samples/web/target10/mult
iselect/web/out/multiselect.html"> |
| 865 </iframe> | 865 </iframe> |
| 866 | 866 |
| 867 The source code for this example is available on github: | 867 The source code for this example is available on github: |
| 868 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get10/multiselect" | 868 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar
get10/multiselect" |
| 869 target="_blank">multiselect</a>. | 869 target="_blank">multiselect</a>. |
| 870 | 870 |
| 871 Key-value pairs in a map called `books` contain the data | 871 Key-value pairs in a map called `books` contain the data |
| 872 for the <select> element. | 872 for the <select> element. |
| 873 The keys are strings and the values are boolean. | 873 The keys are strings and the values are boolean. |
| 874 | 874 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 ###What next? | 972 ###What next? |
| 973 | 973 |
| 974 Try our | 974 Try our |
| 975 <a href="/codelabs/web-ui-writer/index.html" target="_blank"><i class="icon-beak
er"> </i>Codelab</a>. | 975 <a href="/codelabs/web-ui-writer/index.html" target="_blank"><i class="icon-beak
er"> </i>Codelab</a>. |
| 976 In this step-by-step guide, you’ll build a simple, | 976 In this step-by-step guide, you’ll build a simple, |
| 977 single-page, modern web app for desktop and mobile. | 977 single-page, modern web app for desktop and mobile. |
| 978 | 978 |
| 979 {% endcapture %} | 979 {% endcapture %} |
| 980 | 980 |
| 981 {% include tutorial.html %} | 981 {% include tutorial.html %} |
| OLD | NEW |