AngularJS Example:

by erichbschulz

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css">
<p class="text-success">This is an example of using angular. This example has an expandable collection of tasks. A "parse" function is called as the app starts and then on adding each new task</p>
<div ng-app>  <div ng-controller="TaskCtrl">

<table>
    <tr>
        <td>Election\tasks</td>
        <td ng-repeat="(task_type, n) in task_list">{{task_type}}</td>
    </tr>
    <tr ng-repeat="(election, n) in elections">
        <td>{{election}}</td>
        <td ng-repeat="(task_type, n) in task_list" title="{{ election }} {{task_type}}">{{ task_index[election][task_type].done ? 'Y' : 'N' }}
            <!-- {{task_index[election][task_type] | json }} -->
        </td>
    </tr>
</table>

<h2>Add a new task</h2>

    <form ng-submit="addTodo()">
        <input type="text" ng-model="todoText" size="30" placeholder="add new task here">
        <input class="btn-primary" type="submit" value="add">
            <p>Use the same format as EMS task: <code>[election]_[task]</code></p>
    </form>
            
     <h2>Tasks as a list</h2>
        <ul class="unstyled">
            <li ng-repeat="todo in todos">
                <input type="checkbox" ng-model="todo.done"> <span class="done-{{todo.done}}">{{todo.text}}</span>

            </li>
        </ul>
         <h2>Elections</h2><pre>{{elections}}</pre> 
         <h2>Task List</h2><pre>{{task_list}}</pre> 
         <h2>Tasks Index</h2><pre>{{task_index}}</pre> 
    </div>
</div>

CSS

.done-true {
    text-decoration: line-through;
    color: grey;
}

JavaScript

function TaskCtrl($scope) {
    $scope.todos = [{
        text: 'learn_angular',
        done: true
    }, {
        text: 'build_angular',
        done: false
    }, {
        text: 'blah_angular',
        done: false
    }, {
        text: 'learn_fish',
        done: true
    }, {
        text: 'build_fish',
        done: false
    }, {
        text: 'blah_fish',
        done: false
    }, {
        text: 'learn_bob',
        done: true
    }, {
        text: 'build_bob',
        done: false
    }, {
        text: 'blah_bob',
        done: false
    }, ];

    $scope.addTodo = function () {
        $scope.todos.push({
            text: $scope.todoText,
            done: false
        });
        $scope.todoText = '';
        parse();
    };



    var parse = function () {
        console.log("starting parse");
        var lastWord = function (s) {
            return s.split('_').pop();
        }
        var firstWord = function (s) {
            return s.substr(0, s.indexOf("_"));
        }
        var increment = function (list, key) {
            list[key] = list[key] ? list[key] + 1 : 1;
        }
        var tasks = $scope.todos;
        angular.forEach(tasks, function (task) {
            var election = firstWord(task.text);
            var task_id = lastWord(task.text);
            increment($scope.elections, election);
            increment($scope.task_list, task_id);
            if (!$scope.task_index[election]) {
                $scope.task_index[election] = {};
            }
            $scope.task_index[election][task_id] = task;
        });
    };

    $scope.elections = {};
    $scope.task_list = {};
    $scope.task_index = {};


    parse();
}