User Input

Use the event syntax (eventName) to make your application respond to user input.

You can specify the event handler—a method in the component controller—like this:

<input (keyup)="myControllerMethod()">

As in previous examples, you can make element references available to other parts of the template as a local variable using the # syntax. Using # and events, you can write the old "update text as you type" example:

<input #myname (keyup)> <p>{{myname.value}}</p>

In that example, #myname creates a local variable in the template that the <p> element can refer to. The (keyup) tells Angular to trigger updates when it gets a keyup event. And {{myname.value}} binds the text node of the <p> element to the input's value property.

Let's do something a little more complex, where the user enters items that the app adds to a list:

Example of Todo App

Create a list property

With the default files in place, create a TodoController class to manage interactions with the list. Inside TodoController, add a list with some initial items. Then add a method that adds new items to the list.

class TodoList { List<String> todos =[ 'Eat breakfast', 'Walk dog', 'Breathe', 'Learn Angular' ]; addTodo(String todo) { todos.add(todo); } }
Production Best Practice

As shown in the previous example, a production application you would separate the model out into another class and inject it into TodoController. We've omitted that here for brevity.



Display the list of todos

Using the *ng-for iterator, create an <li> for each item in the todos list and set its text to the value.

<ul> <li *ng-for="#todo of todos"> {{ todo }} </li> </ul>

Add todos to the list via button click

Now, add a text input and a button for users to add items to the list. As you saw above, you can create a local variable reference in your template with #varname. Call it #todotext here.

<input #todotext>

Specify the target of the click event binding as your controller's addTodo() method and pass it the value. Since you created a reference called todotext, you can get the value with todotext.value.

<button (click)="addTodo(todotext.value)">Add Todo</button>

To make pressing Enter do something useful, you can add a keyup event handler to the input field. This event handler uses APIs defined in dart:html, so be sure to import that library.

import 'dart:html'; ... // In the template: <input #todotext (keyup)="doneTyping(\$event)"> ... // In the component controller class: doneTyping(KeyboardEvent event) { if (event.keyCode == KeyCode.ENTER) { InputElement e = event.target; addTodo(e.value); e.value = null; } }

Final code

library user_input.todo_list; import 'dart:html'; import 'package:angular2/angular2.dart'; @Component(selector: 'todo-list') @View( // An alternative to using \$event is to use a raw string instead. // For example, change "template: '''" to "template: r'''". template: ''' <ul> <li *ng-for="#todo of todos"> {{ todo }} </li> </ul> <input #todotext (keyup)="doneTyping(\$event)"> <button (click)="addTodo(todotext.value)">Add Todo</button> ''', directives: const [NgFor]) class TodoList { List<String> todos = [ 'Eat breakfast', 'Walk dog', 'Breathe', 'Learn Angular' ]; addTodo(String todo) { todos.add(todo); } doneTyping(KeyboardEvent event) { if (event.keyCode == KeyCode.ENTER) { InputElement e = event.target; addTodo(e.value); e.value = null; } } }import 'package:angular2/bootstrap.dart'; import 'package:user_input/todo_list.dart'; main() { bootstrap(TodoList); }<!DOCTYPE html> <html> <head> <title>User Input</title> <link rel="stylesheet" href="style.css"> <script async src="main.dart" type="application/dart"></script> <script async src="packages/browser/dart.js"></script> </head> <body> <todo-list></todo-list> </body> </html>name: user_input description: User Input example version: 0.0.1 dependencies: angular2: 2.0.0-alpha.45 browser: ^0.10.0 transformers: - angular2: entry_points: web/main.dart

Next Step

Forms