Angular Todo App

ToDo App

by Andy Bulka

HTML

<script type="text/javascript" ng:autobind
src="http://code.angularjs.org/0.9.18/angular-0.9.18.js"></script>

<div ng:controller="TodoCtrl">
    <input type="text" name="todoText" size="35"
    placeholder="enter your todo here"/>
    <button ng:click="addTodo()">add</button> <br/>
    <label>{{remaining}} remaining</label>
    <button ng:click="removeDone()">remove done</button><br/>
    <ul ng:repeat="todo in todos">
        <li>
            <input type="checkbox" name="todo.done" ng:click="recalc()">
            <!-- updates the css class to done_true or done_false -->
            <span ng:class="'done_' + todo.done">{{todo.text}}</span><br/>
        </li>
    </ul>
</div>

CSS

.done_false {text-decoration: none; color: red;}
.done_true {text-decoration: line-through; color: gray;}

JavaScript

function TodoCtrl() {
    var scope = this;
    
    // initialize controller's model    
    this.todos = [{
        text: "learn Angular",
        done: true},
    {
        text: "build Angular app",
        done: false},
    {
        text: "show off Angular app",
        done: false}];
    
    // Define member functions
    this.addTodo = function() {
        scope.todos.push({
            text: scope.todoText,
            done: false
        });
        scope.remaining++;
        scope.todoText = "";
    };

    this.recalc = function() {
        scope.remaining = scope.todos.length;
        angular.forEach(scope.todos, function(todo) {
            if (todo.done) {
                scope.remaining--;
            }
        });
    };

    this.removeDone = function() {
        var todos = scope.todos;
        scope.todos = [];
        
        angular.forEach(todos, function(todo) {
            if (!todo.done) {
                scope.todos.push(todo);
            }
        });
    };

    // call recalc once to update the model's 'remaining' value
    // Note: this needs to be called after definition
    this.recalc();
}