Created
February 19, 2014 01:15
-
-
Save bruschill/9084274 to your computer and use it in GitHub Desktop.
Angular todo app with list management
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var rpgtd = angular.module('rpgtd', []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en" ng-app="rpgtd"> | |
<head> | |
<title>RPGTD</title> | |
<link rel="stylesheet" href="/css/base.css"/> | |
<link rel="stylesheet" href="/css/grid.css"/> | |
<link rel="stylesheet" href="/css/lists.css"/> | |
<link rel="stylesheet" href="/css/tasks.css"/> | |
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script> | |
</head> | |
<body ng-cloak> | |
<div class="pure-g-r"> | |
<div class="grid"> | |
<div class="col-1-5"> | |
<div ng-controller="ListsController"> | |
<header id="lists-header"> | |
<h1>Lists</h1> | |
<item-input add-fn="addList()" model-attr="newListName" placeholder-text="List name..."></item-input> | |
<lists-detail></lists-detail> | |
</header> | |
</div> | |
</div> | |
<div class="col-4-5"> | |
<div ng-controller="TasksController"> | |
<header id="list-header" ng-show="!!listName"> | |
<h1>{{ listName }}</h1> | |
<item-input add-fn="addTask()" model-attr="newTaskName" placeholder-text="Task name..."></item-input> | |
<tasks-detail></tasks-detail> | |
</header> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script src="js/app.js"></script> | |
<script src="js/decorators/onRootScope.js"></script> | |
<script src="js/services/listStorage.js"></script> | |
<script src="js/services/taskStorage.js"></script> | |
<script src="js/directives/itemInput.js"></script> | |
<script src="js/controllers/listsController.js"></script> | |
<script src="js/directives/listsDetail.js"></script> | |
<script src="js/controllers/tasksController.js"></script> | |
<script src="js/directives/tasksDetail.js"></script> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<form id="item-form" ng-submit="addFn()"> | |
<input id="new-item" placeholder="{{placeholderText}}" ng-model="modelAttr"></input> | |
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict;' | |
rpgtd.directive('itemInput', function() { | |
return { | |
restrict: 'E', | |
replace: true, | |
scope: { | |
addFn: '&', | |
modelAttr: '=', | |
placeholderText: '@' | |
}, | |
templateUrl: 'views/itemInput.html' | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
rpgtd.controller('ListsController', ['$scope', '$rootScope', 'listStorage', 'filterFilter', function ListsController($scope, $rootScope, listStorage, filterFilter) { | |
var lists = $scope.lists = listStorage.get(); | |
$scope.newListName = ''; | |
$scope.addList = function() { | |
var newListName = $scope.newListName.trim(); | |
if(!newListName.length) { | |
return; | |
} | |
lists.push({ | |
name: newListName, | |
tasks: {} | |
}); | |
listStorage.put(lists); | |
$scope.newListName = ''; | |
}; | |
$scope.selectList = function(list) { | |
localStorage.setItem('rpgtd-selected-list', list.name); | |
$rootScope.$emit('listSelected', list.name); | |
}; | |
//TODO this removes the list, but also removes the tasks from every other list as well... | |
$scope.removeList = function(list) { | |
if(list.name === localStorage.getItem('rpgtd-selected-list')) { | |
localStorage.removeItem('rpgtd-selected-list'); | |
$rootScope.$emit('listSelected', null); | |
} | |
lists.splice(lists.indexOf(list), 1); | |
listStorage.put(lists); | |
}; | |
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section ng-show="lists.length"> | |
<ul class="lists"> | |
<li class="list-container cf" ng-repeat="list in lists | filter:statusFilter track by $index"> | |
<div class="list-name" ng-click="selectList(list)">{{ list.name }}</div> | |
<button class="btn-destroy-list" ng-click="removeList(list)">Remove</button> | |
</li> | |
</ul> | |
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
rpgtd.directive('listsDetail', function() { | |
return { | |
restrict: 'E', | |
replace: true, | |
templateUrl: 'views/listsDetail.html', | |
controller: 'ListsController' | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
rpgtd.service('taskStorage', function() { | |
var STORAGE_ID = 'rpgtd-lists'; | |
return { | |
getTasks: function(listName) { | |
var lists = angular.fromJson(localStorage.getItem(STORAGE_ID)); | |
if(!listName || !lists) { | |
return []; | |
} else { | |
for(var i = 0; i < lists.length; i++) { | |
if(lists[i].name === listName){ | |
var tasks = lists[i].tasks; | |
if(Object.keys(tasks).length === 0) { | |
return []; | |
} else { | |
return tasks; | |
} | |
} | |
} | |
} | |
}, | |
putTasks: function(tasks, listName) { | |
var lists = angular.fromJson(localStorage.getItem(STORAGE_ID)); | |
for(var i = 0; i < lists.length; i++) { | |
if(lists[i].name === listName){ | |
lists[i].tasks = tasks; | |
localStorage.setItem(STORAGE_ID, angular.toJson(lists)); | |
} | |
} | |
} | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rpgtd.config(['$provide', function($provide){ | |
$provide.decorator('$rootScope', ['$delegate', function($delegate){ | |
$delegate.constructor.prototype.$onRootScope = function(name, listener){ | |
var unsubscribe = $delegate.$on(name, listener); | |
this.$on('$destroy', unsubscribe); | |
}; | |
return $delegate; | |
}]); | |
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
rpgtd.controller('TasksController', ['$scope', 'taskStorage', 'filterFilter', function TasksController($scope, taskStorage, filterFilter) { | |
var listName = $scope.listName = localStorage.getItem('rpgtd-selected-list') || null | |
var tasks = $scope.tasks = taskStorage.getTasks(listName); | |
$scope.newTaskName = ''; | |
$scope.remainingTasksCount = filterFilter(tasks, {completed: false}).length; | |
$scope.$onRootScope('listSelected', function(event, selectedListName) { | |
listName = $scope.listName = selectedListName; | |
tasks = $scope.tasks = taskStorage.getTasks(selectedListName); | |
$scope.remainingTasksCount = filterFilter(tasks, {completed: false}).length; | |
}); | |
$scope.addTask = function() { | |
var newTaskName = $scope.newTaskName.trim(); | |
if(!newTaskName.length) { | |
return; | |
} | |
tasks.push({ | |
name: newTaskName, | |
completed: false | |
}); | |
taskStorage.putTasks(tasks, listName); | |
$scope.newTaskName = ''; | |
$scope.remainingTasksCount++; | |
}; | |
$scope.removeTask = function(task) { | |
$scope.remainingTasksCount -= task.completed ? 0 : 1; | |
tasks.splice(tasks.indexOf(task), 1); | |
taskStorage.putTasks(tasks, listName); | |
}; | |
$scope.taskCompleted = function(task) { | |
$scope.remainingTasksCount += task.completed ? -1 : 1; | |
taskStorage.putTasks(tasks, listName); | |
}; | |
}]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<section ng-show="tasks.length"> | |
<ul class="tasks"> | |
<li class="task-container cf" ng-repeat="task in tasks | filter:statusFilter track by $index"> | |
<div class="task-info"> | |
<input type="checkbox" class="task-complete" ng-model="task.completed" ng-change="taskCompleted(task)"></input> | |
<div class="task-name">{{ task.name }}</div> | |
</div> | |
<button class="btn-task-destroy" ng-click="removeTask(task)">Remove</button> | |
</li> | |
</ul> | |
<footer id="footer" ng-show="tasks.length"> | |
<span id="task-count"> | |
<strong>{{ remainingTasksCount }} <span ng-pluralize count="remainingTasksCount" when="{one: 'task left', other: 'tasks left'}"></span></strong> | |
</span> | |
</footer> | |
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
rpgtd.directive('tasksDetail', function() { | |
return { | |
restrict: 'E', | |
replace: true, | |
templateUrl: 'views/tasksDetail.html', | |
controller: 'TasksController' | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment