Task List

by Simon Bingham

HTML

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
<body ng-app="tasklist" ng-controller="TaskListController as taskListCtrl">
	<div class="container">
		<h1>Task List</h1>

		<form ng-submit="taskListCtrl.addTask(task)">
			<table class="table">
				<tr>
					<td style="width:20px;"></td>
					<td><input type="text" ng-model="taskListCtrl.task.text"></td>
				</tr>
			</table>
		</form>

		<table class="table">
			<tr ng-repeat="task in taskListCtrl.tasks | orderBy:['done', '-created']">
				<td style="width:20px;"><input type="checkbox" ng-model="task.done"></td>
				<td class="done-{{task.done}}">
					<input type="text" ng-model="task.text" ng-blur="showInput=false" ng-show="showInput" focus-input-on="{{showInput}}">
					<a href="" ng-click="showInput=true" ng-hide="showInput">{{task.text}}</a>
				</td>
			</tr>
		</table>
	</div>
</body>

CSS

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

JavaScript

(function () {
	var app = angular.module('tasklist', []);

	app.controller('TaskListController', function() {
		var taskList = this;

		taskList.tasks = [
			{text:'do something 1', done:false, created:new Date(14, 1, 1)},
			{text:'do something 2', done:true, created:new Date(14, 1, 2)},
			{text:'do something 3', done:false, created:new Date(14, 1, 3)},
			{text:'do something 4', done:true, created:new Date(14, 1, 4)},
			{text:'do something 5', done:true, created:new Date(14, 1, 5)}
		];

		taskList.addTask = function (task) {
			taskList.task.done = false;
			taskList.task.created = new Date();
			taskList.tasks.push(taskList.task);
			taskList.task = {};
		};
	});
    
	app.directive('focusInputOn', function ($timeout) {
		return {
			restrict: 'A',
			link: function focusInputOnPostLink(scope, elem, attrs) {
				attrs.$observe('focusInputOn', function (newValue) {
					if (newValue) {
						// since the element will become visible (and focusable) after the next render event, we need to wrap the code in '$timeout'
						$timeout(function () {
							var el = elem[0];
							el.focus();
							el.selectionStart = el.selectionEnd = el.value.length;
						});
					}
				});
			}
		};
	});    

})();