User Input

Responding to user input with event syntax

You can make your application respond to user input by using the event syntax. The event syntax starts with an event name surrounded by parenthesis: (event). A controller function is then assigned to the event name: (event)="controllerFn()".

For a particular control like an input you can have it call methods on your controller on keyup event like so:

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

Local variables

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

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

The #myname creates a local variable in the template that we'll refer to below in the <p> element. The (keyup) tells Angular to trigger updates when it gets a keyup event. And the {{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 users enter items and add them to a list like this:

Example of Todo App

Create an array property

With the default bootstrapping in place, create a controller class that will manage interactions with the list. Inside the controller, add an array with an initial list of items. Then add a method that pushes new items on the array when called.

//TypeScript class TodoList { todos: Array<string>; constructor() { this.todos = ["Eat Breakfast", "Walk Dog", "Breathe"]; } addTodo(todo: string) { this.todos.push(todo); } }//ES5 function TodoList() { this.todos = ["Eat Breakfast", "Walk Dog", "Breathe"]; this.addTodo = function(todo) { this.todos.push(todo); }; }
Production Best Practice

As with the previous example, in a production application you will separate your model out into another class and inject it into TodoList. We've omitted it here for brevity.

Display the list of todos

Using the *ng-for iterator, create an <li> for each item in the todos array 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>

Lastly, 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>

And then create the doneTyping() method on TodoList and handle adding the todo text.

doneTyping($event) { if($event.which === 13) { this.addTodo($event.target.value); $event.target.value = null; } }

Final Code

//TypeScript import {Component, View, bootstrap, NgFor} from 'angular2/angular2'; @Component({ selector: 'todo-list' }) @View({ 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: [NgFor] }) class TodoList { todos: Array<string>; constructor() { this.todos = ["Eat Breakfast", "Walk Dog", "Breathe"]; } addTodo(todo: string) { this.todos.push(todo.value); } doneTyping($event) { if($event.which === 13) { this.addTodo($event.target.value); $event.target.value = null; } } } bootstrap(TodoList);//ES5 function TodoList() { this.todos = ["Eat Breakfast", "Walk Dog", "Breathe"]; this.addTodo = function(todo) { this.todos.push(todo.value); }; this.doneTyping = function($event) { if($event.which === 13) { this.addTodo($event.target.value); $event.target.value = null; } } } TodoList.annotations = [ new angular.ComponentAnnotation({ selector: "todo-list" }), new angular.ViewAnnotation({ template: '<ul>' + '<li *ng-for="#todo of todos">' + '{{ todo }}' + '</li>' + '</ul>' + '<input #textbox (keyup)="doneTyping($event)">' + '<button (click)="addTodo(textbox.value)">Add Todo</button>', directives: [angular.NgFor] }) ]; document.addEventListener("DOMContentLoaded", function() { angular.bootstrap(TodoList); });

Next Step

Forms