diff --git a/modules/examples/src/model_driven_forms/index.html b/modules/examples/src/model_driven_forms/index.html
new file mode 100644
index 0000000000..54f575abc2
--- /dev/null
+++ b/modules/examples/src/model_driven_forms/index.html
@@ -0,0 +1,19 @@
+
+
+
+ Model Driven Forms
+
+
+
+
+
+ Loading...
+
+
+ $SCRIPTS$
+
+
diff --git a/modules/examples/src/model_driven_forms/index.ts b/modules/examples/src/model_driven_forms/index.ts
new file mode 100644
index 0000000000..27dff421f1
--- /dev/null
+++ b/modules/examples/src/model_driven_forms/index.ts
@@ -0,0 +1,149 @@
+import {bootstrap, onChange, NgIf, Component, Directive, View, Ancestor} from 'angular2/angular2';
+import {
+ formDirectives,
+ ControlDirective,
+ Validators,
+ FormModelDirective,
+ FormBuilder
+} from 'angular2/forms';
+
+import {ObservableWrapper} from 'angular2/src/facade/async';
+import {RegExpWrapper, print, isPresent} from 'angular2/src/facade/lang';
+
+import {reflector} from 'angular2/src/reflection/reflection';
+import {ReflectionCapabilities} from 'angular2/src/reflection/reflection_capabilities';
+
+/**
+ * Custom validator.
+ */
+function creditCardValidator(c): StringMap {
+ if (isPresent(c.value) && RegExpWrapper.test(new RegExp("^\\d{16}$"), c.value)) {
+ return null;
+ } else {
+ return {"invalidCreditCard": true};
+ }
+}
+
+/**
+ * This is a component that displays an error message.
+ *
+ * For instance,
+ *
+ *
+ *
+ * Will display the "is required" error if the control is empty, and "invalid credit card" if the
+ * control is not empty
+ * but not valid.
+ *
+ * In a real application, this component would receive a service that would map an error code to an
+ * actual error message.
+ * To make it simple, we are using a simple map here.
+ */
+@Component({selector: 'show-error', properties: ['controlPath: control', 'errorTypes: errors']})
+@View({
+ template: `
+ {{errorMessage}}
+ `,
+ directives: [NgIf]
+})
+class ShowError {
+ formDir;
+ controlPath: string;
+ errorTypes: List;
+
+ constructor(@Ancestor() formDir: FormModelDirective) { this.formDir = formDir; }
+
+ get errorMessage() {
+ var c = this.formDir.form.find(this.controlPath);
+ for (var i = 0; i < this.errorTypes.length; ++i) {
+ if (isPresent(c) && c.touched && c.hasError(this.errorTypes[i])) {
+ return this._errorMessage(this.errorTypes[i]);
+ }
+ }
+ return null;
+ }
+
+ _errorMessage(code) {
+ var config = {'required': 'is required', 'invalidCreditCard': 'is invalid credit card number'};
+ return config[code];
+ }
+}
+
+
+@Component({selector: 'model-driven-forms', appInjector: [FormBuilder]})
+@View({
+ template: `
+ Checkout Form (Model Driven)
+
+
+ `,
+ directives: [formDirectives, ShowError]
+})
+class ModelDrivenForms {
+ form;
+
+ constructor(fb: FormBuilder) {
+ this.form = fb.group({
+ "firstName": ["", Validators.required],
+ "middleName": [""],
+ "lastName": ["", Validators.required],
+ "creditCard": ["", Validators.compose([Validators.required, creditCardValidator])],
+ "amount": [0, Validators.required],
+ "email": ["", Validators.required],
+ "comments": [""]
+ });
+ }
+
+ onSubmit() {
+ print("Submitting:");
+ print(this.form.value);
+ }
+}
+
+export function main() {
+ reflector.reflectionCapabilities = new ReflectionCapabilities();
+ bootstrap(ModelDrivenForms);
+}