diff --git a/LICENSE b/LICENSE index 187d4d6..d598d52 100644 --- a/LICENSE +++ b/LICENSE @@ -5,8 +5,8 @@ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -*Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the diff --git a/public/css/boot.css b/public/css/boot.css deleted file mode 100644 index 2794bfa..0000000 --- a/public/css/boot.css +++ /dev/null @@ -1,4 +0,0 @@ -body { - padding-top: 60px; -} - diff --git a/public/css/main.css b/public/css/main.css index edbf2a1..3bcf2e1 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -1,3 +1,14 @@ +/* + Copyright 2013 Joshua Marsh. All rights reserved. Use of this + source code is governed by a BSD-style license that can be found in + the LICENSE file. +*/ + +body { + /* We add the padding for the fixed header. */ + padding-top: 60px; +} + .all-scroll-cursor { cursor: all-scroll; } @@ -6,34 +17,36 @@ cursor: pointer; } +/* This is the style of a completed list item. */ .done-true { text-decoration: line-through; color: grey; } +/* To enable sorting, we use a list instead of a table, so we +implement the table striping for lists. */ .list-striped > li { - line-height: 20px; - padding: 8px; - border-top: 1px solid #dddddd; + line-height: 20px; + padding: 8px; + border-top: 1px solid #dddddd; } .list-striped li:nth-child(odd) { background-color: #f9f9f9; } -.pad-bottom { +/* This is used to make a reasonable amount of space between the forms +and buttons and the list items. */ +.pad-bottom { padding-bottom: 15px; } +/* The text box is slightly off, so we move it up a bit. */ .editing-item { margin-top: -5px; - display: none; -} - -.viewing-item { - display: inline; } +/* The drag icon is slightly off, so we move it up a bit. */ .drag-icon { margin-top: -5px; } \ No newline at end of file diff --git a/public/header.html b/public/header.html deleted file mode 100644 index e69de29..0000000 diff --git a/public/index.html b/public/index.html index ea4b8a7..be4fe9d 100644 --- a/public/index.html +++ b/public/index.html @@ -1,9 +1,14 @@ + List App - + @@ -16,20 +21,20 @@ - + - - + + - + - - - + + + @@ -42,7 +47,6 @@ -
@@ -78,11 +82,9 @@
+
- - - diff --git a/public/js/lists.js b/public/js/lists.js index 79af990..005d573 100644 --- a/public/js/lists.js +++ b/public/js/lists.js @@ -1,9 +1,19 @@ +/* + Copyright 2013 Joshua Marsh. All rights reserved. Use of this + source code is governed by a BSD-style license that can be found in + the LICENSE file. +*/ + // ListsCtrl is the controller for viewing all lists. function ListsCtrl($scope, $location, List) { + // The entire list box is clickable and this function handles that + // by changing the location path. $scope.view = function(key) { $location.path('/view/' + key + '/'); }; + // This handles clicking the copy button. It pops up the modal and + // prepares it's name. $scope.copymodal = function(key, name, event) { $scope.copyKey = key; $scope.copyName = "Copy of " + name; @@ -14,7 +24,7 @@ function ListsCtrl($scope, $location, List) { event.stopPropagation(); }; - + // This function actually makes the copy of the list. $scope.copy = function() { $('#copyModal').modal('hide'); @@ -27,6 +37,8 @@ function ListsCtrl($scope, $location, List) { }; + // This function opens up the modal to verify that + // they want to delete the list. $scope.delete = function(key, event) { $scope.deleteKey = key; @@ -36,6 +48,7 @@ function ListsCtrl($scope, $location, List) { event.stopPropagation(); }; + // This function performs the actual delete. $scope.sure = function() { $('#deleteModal').modal('hide'); List.delete($scope.deleteKey, function() { @@ -45,16 +58,20 @@ function ListsCtrl($scope, $location, List) { }); }; + // This function opens up the new modal box. $scope.new = function() { $('#newModal').modal(); - }; + // If any of the modals click cancel, this is + // called to close it. $scope.back = function() { $('#newModal').modal('hide'); $('#copyModal').modal('hide'); }; + // This creates the new list and redirects you to + // that list. $scope.save = function() { $('#newModal').modal('hide'); List.create({"Name": $scope.name}, function (l) { @@ -62,6 +79,7 @@ function ListsCtrl($scope, $location, List) { }); }; + // To start off, we should get all the lists. List.getall(function (lists) { $scope.lists = lists; }); diff --git a/public/js/rest.js b/public/js/rest.js index 24974c3..2ff6e88 100644 --- a/public/js/rest.js +++ b/public/js/rest.js @@ -1,11 +1,27 @@ +/* + Copyright 2013 Joshua Marsh. All rights reserved. Use of this + source code is governed by a BSD-style license that can be found in + the LICENSE file. +*/ + // This is a module for interacting with the rest framework. angular.module('rest', ['ngResource']) + /* This is an interface to the RESTful User service. */ .factory('User', function($resource) { var User = $resource("/rest/user/", {}, {}); return User; }) + /* This is an interface to the RESTful List service. We have + * to use a service here because go and angular don't play nicely + * together with trailing slashes. + */ .service('List', function($http) { + // Note: All of these functions accept callback + // functions in which the resulting data from the + // server is returned. + + // Create a new list. this.create = function(data, call) { return $http.post("/rest/list/", data) .then(function (response) { @@ -13,6 +29,7 @@ angular.module('rest', ['ngResource']) }); }; + // Save an existing list. this.save = function(data, call) { return $http.put("/rest/list/" + data.Key + "/", data) .then(function (response) { @@ -20,9 +37,11 @@ angular.module('rest', ['ngResource']) }); }; + // Check to see if a list has been modified. this.checkupdate = function(data, call) { return $http.get("/rest/list/" + data.Key + "/") .then(function (response) { + // We are just going to compare LastModified dates. var sdate = Date.parseRFC3339(response.data.LastModified); var mdate = Date.parseRFC3339(data.LastModified); @@ -31,6 +50,7 @@ angular.module('rest', ['ngResource']) }; + // Delete the list wit the given key. this.delete = function(key, call) { return $http.delete("/rest/list/" + key + "/") .then(function(response) { @@ -38,6 +58,7 @@ angular.module('rest', ['ngResource']) }); }; + // Get all lists. this.getall = function(call) { return $http.get("/rest/list/") .then(function(response) { @@ -46,6 +67,7 @@ angular.module('rest', ['ngResource']) }; + // Get a specific list. this.get = function(key, call) { return $http.get("/rest/list/" + key + "/") .then(function(response) { diff --git a/public/js/routing.js b/public/js/routing.js index 0a0f383..90cde52 100644 --- a/public/js/routing.js +++ b/public/js/routing.js @@ -1,3 +1,9 @@ +/* + Copyright 2013 Joshua Marsh. All rights reserved. Use of this + source code is governed by a BSD-style license that can be found in + the LICENSE file. +*/ + // This is the routing mechanism. angular.module('list', ['rest']) .config(function ($routeProvider) { @@ -14,6 +20,8 @@ angular.module('list', ['rest']) } ) + // This is used to auto-focus the items then they are switched + // from a span to a text box. .directive('ngHasfocus', function() { return function(scope, element, attrs) { scope.$watch(attrs.ngHasfocus, function (nVal, oVal) { diff --git a/public/js/user.js b/public/js/user.js index a6e6446..d5f1cf8 100644 --- a/public/js/user.js +++ b/public/js/user.js @@ -1,3 +1,9 @@ +/* + Copyright 2013 Joshua Marsh. All rights reserved. Use of this + source code is governed by a BSD-style license that can be found in + the LICENSE file. +*/ + // UserCtrl is the controller for part of the site that lists all of // the lists. function UserCtrl($scope, User) { diff --git a/public/js/view.js b/public/js/view.js index 1687995..4c1445c 100644 --- a/public/js/view.js +++ b/public/js/view.js @@ -1,3 +1,9 @@ +/* + Copyright 2013 Joshua Marsh. All rights reserved. Use of this + source code is governed by a BSD-style license that can be found in + the LICENSE file. +*/ + // ViewCtrl is the controller for viewing and updating lists. function ViewCtrl($scope, $location, $routeParams, $timeout, List) { @@ -21,11 +27,14 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) { }; $scope.timer = $timeout($scope.checkupdate, 30000); + // This is called when the update button is pressed. $scope.update = function() { if ($scope.dirty) { - // Ask them if they want to merge their changes. + // Ask them if they want to merge their changes + // if there are changes. $('#updateModal').modal(); } else { + // Otherwise, we can just update. List.get($routeParams.id, function(l) { $scope.list = l; }); @@ -33,12 +42,16 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) { } }; + // This is called when they want to merge their changes with + // the latest list. $scope.updatemerge = function() { $scope.save(); $scope.updatable = false; $('#updateModal').modal('hide'); }; + // This is called when they want to just get the updated list + // and lose their changes. $scope.updateoverwrite = function() { List.get($routeParams.id, function(l) { $scope.list = l; @@ -47,15 +60,20 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) { $('#updateModal').modal('hide'); }; + // When the order of the list items change, this is called to + // update the internal array that is storing the list items. $scope.sort = function(event, ui) { var ids = $("#sortablelist").sortable("toArray"); var items = new Array(); + + // Make a new list from the array. ids.forEach(function(e, i, a) { var eid = e.replace("list-item-", ""); var id = parseInt(eid); items.push($scope.list.Items[id]); }); - + + // Set the list ot be the newly made list. $scope.list.Items = items; $scope.dirty = true; }; @@ -66,6 +84,7 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) { $scope.list.Items = new Array(); } + // We unshift to add it to the top. $scope.list.Items.unshift({ "Name": $scope.newitem, "Completed": false, @@ -115,11 +134,17 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) { return !item.Delete; }; + // Stop propogating a click. This is mainly used by the list + // item input text boxes so they don't change the completed + // state of the item when they are clicked. $scope.noclick = function(event) { // Don't let it fall through to the view. event.stopPropagation(); }; + // This changes the state of the item being edited. There + // are two special values: -1 is for no item, and -2 is the + // title of the list. $scope.edit = function(id, event) { $scope.editing = id; $scope.dirty = true; @@ -143,6 +168,9 @@ function ViewCtrl($scope, $location, $routeParams, $timeout, List) { }); }); + // Start out with cursor in the add text box. $('#newitem').focus(); + + // We start out not editing any list. $scope.editing = -1; } \ No newline at end of file diff --git a/public/lists.html b/public/lists.html index 707e160..29b0ec5 100644 --- a/public/lists.html +++ b/public/lists.html @@ -1,22 +1,28 @@ +

Lists

- - - - - + + + + + +
-
Name
-
- -
-
+
Name
+
+ +
+
@@ -41,6 +47,8 @@

Lists

+ @@ -91,18 +99,20 @@

New List

+