For lots more examples, and more context and details, be sure to check out the Dart Tutorials . You can find the code for this post at my Github account.

Step 1: Install the Web UI package

Open up pubspec.yaml (used by the pub package manager ) and add the dependencies for Web UI.

dependencies :

browser : any

web_ui : any





Step 2: Create the model class





This class is for our "business object". It is bound to the form, so we make it observable





library person;





import 'package:web_ui/web_ui.dart' ;





@ observable

class Person {

String firstName ;

String lastName ;

double age = 0.0 ; // not an int because web ui loves doubles

}





Step 3: Create the custom element HTML





This custom element, polyfilled by Web UI , wraps the form and makes it easy to reuse. The custom element is bound to an instance of Person, our model class. The tag contains the structure of this custom element. Notice the submit event runs the submit() method of this custom component (see in the next step). The $event object, representing the submit event, is passed to submit().









< element name= "person-form" constructor= "PersonForm" extends= "div" >

< template >

< div id= "message" ></ div >

< form method= "post" on-submit="submit($event)" >

< input type= "text" bind-value= "person.firstName" name= "firstName" >

< input type= "text" bind-value= "person.lastName" name= "lastName" >

< input type= "number" bind-value-as-number= "person.age" name= "age" >

< input type= "submit" >

</ form >

</ template >

< script type= "application/dart" src= "personform.dart" ></ script >

</ element >





Step 4: Create the custom element Dart code





If a custom element needs custom behavior, you can implement it with Dart. Each custom element tag you use on the page as an instance of its corresponding class. The submit() method is called when the form is submitted (see the on-submit binding from Step 3). The person and action fields of the PersonForm class get initialized by attribute and data bindings from the usage of the custom element tag.





In this case, we disable the default behavior of form submission so we don't incur a page reload. We use HttpRequest to submit the form data, and update a div inside our custom element with the response text.





import 'package:web_ui/web_ui.dart' ;

import 'person.dart' ;

import 'dart:html' ;





class PersonForm extends WebComponent {

Person person ;

String action ;

submit(Event e) {

e.preventDefault();



FormElement form = e.target as FormElement;

form.action = action;



HttpRequest.request(form.action,

method:form.method,

sendData:new FormData(form))

.then((HttpRequest req) {

host.query('#message').text = req.responseText;

})

.catchError((e) => print(e));

}

}





Step 5: Import and use the custom element





Use a <link> tag to import the custom element. Use the custom element with is="person-form" attribute on a <div>. An instance of person (created in the next step) is bound to the custom element. The action attribute on div is used to set the action via static data binding.





< html >

< head >

< meta charset= "utf-8" >

< link rel= "stylesheet" href= "parse_form_submit.css" >

< link rel= "import" href= "personform.html" >

</ head >

< body >

< h1 >Forms</ h1 >

< div action= "http://localhost:8888/submit" is= "person-form" person= "{{person}}" ></ div >





< script type= "application/dart" src= "parse_form_submit.dart" ></ script >

< script src= "packages/browser/dart.js" ></script>

</body>

</html>





Step 6: Create the app's main code





All this app needs is one instance of Person. The instance defined here is visible to the page, and is the same as used in the custom element from Step 5 (person="{{person}}"). The main() method is empty, because Web UI handles all the binding, initialization, etc.





import 'person.dart' ;





Person person = new Person();





main () { }





Step 7: Write the server





Dart's dart:io library help you write command-line and server-side application. We use the builtin HTTP server functionality to listen for POST requests, parse the form data into a Map, enable CORS headers (so pages from any origin can submit to this server), and send back a string version of the original form data.





import 'dart:io' ;





main () {

HttpServer.bind( '0.0.0.0' , 8888 ).then((HttpServer server) {

server.listen((HttpRequest req) {

if (req. uri . path == '/submit' && req. method == 'POST' ) {

print( 'received submit' );

HttpBodyHandler.processRequest(req).then((HttpBody body) {

print(body. body . runtimeType ); // Map

req. response . headers .add( 'Access-Control-Allow-Origin' , '*' );

req. response . headers .add( 'Content-Type' , 'text/plain' );

req. response . statusCode = HttpStatus.CREATED ;

req. response .write(body. body .toString());

req. response .close();

});

}

});

});

}





Summary





Ta da! You've just used Dart to create a live, data-bound form and wrapped it up in a web component. Then, you wrote a Dart server to parse the form data and return a simple response. Be sure to checkout the Github repo for this post for all the code (as I left out a few things). Is this the best we can do? Probably not, you probably want a more full-featured server-side framework. There are a few in pub.dartlang.org for you to explore.





Learning more





To learn more about Dart, try these resources: