From e3db848e83300300c9d85c791024e9b724096f31 Mon Sep 17 00:00:00 2001 From: AterStrix Date: Thu, 9 Mar 2017 00:07:13 +0200 Subject: [PATCH 1/3] In progress. --- index.html | 9 +++- js/TODOList.js | 7 +++ js/addTaskForm.js | 6 +++ js/addUserForm.js | 88 +++++++++++++++++++++++++++++++++++++ js/app.js | 44 +++++++++++++++++++ js/arrayUtils.js | 60 ++++++++++++++++++++++++++ js/main.js | 12 ++++++ js/task.js | 3 ++ js/tasksList.js | 3 ++ js/user.js | 65 ++++++++++++++++++++++++++++ js/usersList.js | 103 ++++++++++++++++++++++++++++++++++++++++++++ js/validateUtils.js | 20 +++++++++ 12 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 js/TODOList.js create mode 100644 js/addTaskForm.js create mode 100644 js/addUserForm.js create mode 100644 js/app.js create mode 100644 js/arrayUtils.js create mode 100644 js/task.js create mode 100644 js/tasksList.js create mode 100644 js/user.js create mode 100644 js/usersList.js create mode 100644 js/validateUtils.js diff --git a/index.html b/index.html index ebee9a6..59c399f 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,14 @@ Base template - + + + + + + + + diff --git a/js/TODOList.js b/js/TODOList.js new file mode 100644 index 0000000..1eda0bd --- /dev/null +++ b/js/TODOList.js @@ -0,0 +1,7 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + "use strict"; + app.addModule("TODOList", {}); +})(); \ No newline at end of file diff --git a/js/addTaskForm.js b/js/addTaskForm.js new file mode 100644 index 0000000..d85c04a --- /dev/null +++ b/js/addTaskForm.js @@ -0,0 +1,6 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + +})(); \ No newline at end of file diff --git a/js/addUserForm.js b/js/addUserForm.js new file mode 100644 index 0000000..5b8e068 --- /dev/null +++ b/js/addUserForm.js @@ -0,0 +1,88 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + "use strict"; + app.addModule("addUserForm", { + createAddUserForm: createAddUserForm + }); + + var validateUtils = app.getModule("validateUtils"); + + function createAddUserForm(onAddUser) { + var controller = new CreateController(onAddUser); + return createView(controller); + } + + function createView(controller) { + var $viewTemplate = $('\ +
\ + \ + \ + \ +
' + ); + + var $userName = $viewTemplate.find(".userName"); + var $userEmail = $viewTemplate.find(".userEmail"); + + $viewTemplate.find(".addUserButton").on("click", function() { + controller.addUser($userName.val(), $userEmail.val()); + }); + + controller.addResetView(function () { + $userName.val(""); + $userEmail.val(""); + }); + + return $viewTemplate; + } + + function CreateController(onAddUser) { + this._onAddUser = onAddUser; + this._userModel = { + name: "", + email: "" + } + } + CreateController.prototype = { + addUser: addUser, + validateForm: validateForm, + addResetView: addResetView + }; + + function addUser(userName, userEmail) { + this._userModel = { + name: userName, + email: userEmail + }; + if (this.validateForm() && this._onAddUser(this._userModel)) { + this._userModel = { + name: "", + email: "" + }; + this.resetView(); + } + } + + function validateForm() { + var errorMessage = ""; + if (!validateUtils.validateRequired(this._userModel.name)) { + errorMessage += "Field User Name is required\n"; + } + if (!validateUtils.validateRequired(this._userModel.email)) { + errorMessage += "Field User Email is required\n"; + } + else if (!validateUtils.validateEmail(this._userModel.email)) { + errorMessage += "Field User Email is invalid\n"; + } + if (errorMessage) { + alert(errorMessage); + } + return !errorMessage; + } + + function addResetView(resetView) { + this.resetView = resetView; + } +})(); \ No newline at end of file diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..b1a7e8a --- /dev/null +++ b/js/app.js @@ -0,0 +1,44 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + "use strict"; + var modules = {}; + var app = {}; + app.addModule = addModule; + app.getModule = getModule; + app.addMethod = addMethod; + window.app = app; + + function addModule(moduleName, module) { + if (modules[moduleName]) { + throw("Module already exist"); + } + else { + var fn = new Function("return function " + moduleName + "(){}")(); + fn.prototype = module; + modules[moduleName] = fn; + } + } + + function getModule(moduleName) { + if (modules[moduleName]) { + return new modules[moduleName](); + } + else { + throw("Module does not exist"); + } + } + + function addMethod(moduleName, methodName, method) { + if (!modules[moduleName]) { + throw("Module does not exist"); + } + else if (modules[moduleName].prototype[methodName]) { + throw("Method already exist"); + } + else { + modules[moduleName].prototype[methodName] = method; + } + } +})(); \ No newline at end of file diff --git a/js/arrayUtils.js b/js/arrayUtils.js new file mode 100644 index 0000000..55f7544 --- /dev/null +++ b/js/arrayUtils.js @@ -0,0 +1,60 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + "use strict"; + app.addModule("arrayUtils", { + sortArray: sortArray, + findInArray: findInArray + }); + + var emailValidationPattern = /\w+@\w+\.\w+/; + + function sortArray(array, field, direction) { + if ($.type(array[0][field]) === 'date') { + array.sort(function (a, b) { + return sortDate(a[field], b[field]); + }) + } + else if ($.type(array[0][field]) === 'string') { + array.sort(function (a, b) { + return sortText(a[field], b[field]); + }) + } + if (direction === 'ascending') { + array.reverse(); + } + } + + function findInArray(array, value) { + if ($.type(value) === 'object') { + return array.reduce(function (findedValue, elem) { + var finded = true; + for(var key in value) { + if (elem[key] !== value[key]) { + return findedValue; + } + } + return findedValue || elem; + }, undefined); + } + else { + return array.reduce(function (findedValue, elem) { + return findedValue || elem === value ? elem : undefined; + }, undefined); + } + } + + function sortDate(a, b) { + return a - b; + } + + function sortText(a, b) { + if (a.toLowerCase() > b.toLowerCase()) { + return 1; + } + else if (b.toLowerCase() > a.toLowerCase()) { + return -1; + } + } +})(); \ No newline at end of file diff --git a/js/main.js b/js/main.js index e69de29..cdce374 100644 --- a/js/main.js +++ b/js/main.js @@ -0,0 +1,12 @@ +(function () { + var addUserForm = app.getModule("addUserForm"); + var usersList = app.getModule("usersList"); + var users = []; + $("h1").after(addUserForm.createAddUserForm(function (user) { + users.push(user); + $(".addUser").after(usersList.createUsersList(users)); + return true; + })); + + +})(); \ No newline at end of file diff --git a/js/task.js b/js/task.js new file mode 100644 index 0000000..5a2e6df --- /dev/null +++ b/js/task.js @@ -0,0 +1,3 @@ +/** + * Created by AterStrix on 08.03.2017. + */ diff --git a/js/tasksList.js b/js/tasksList.js new file mode 100644 index 0000000..5a2e6df --- /dev/null +++ b/js/tasksList.js @@ -0,0 +1,3 @@ +/** + * Created by AterStrix on 08.03.2017. + */ diff --git a/js/user.js b/js/user.js new file mode 100644 index 0000000..2cc5507 --- /dev/null +++ b/js/user.js @@ -0,0 +1,65 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + app.addModule("user", { + createUser: createUser + }); + + function createUser(user, onDelete, onAssignChanged) { + var controller = new CreateController(user, onDelete, onAssignChanged); + return createView(controller); + } + + function createView(controller) { + var user = controller.getUser(); + + var $viewTemplate = $('\ +
  • \ +

    '+user.name+'

    \ +

    '+user.email+'

    \ + Assignd \ + \ +
  • ' + ); + + var $assignCheckbox = $viewTemplate.find(".assignCheckbox"); + var $deleteButton = $viewTemplate.find(".deleteButton"); + + $assignCheckbox[0].checked = user.assigned; + + $assignCheckbox.on("change", function() { + controller.changeAssign(this.checked); + }); + + $deleteButton.on("click", function() { + controller.deleteUser(); + }); + + return $viewTemplate; + } + + function CreateController(user, onDelete, onAssignChanged) { + this._user = user || {}; + this._onDelete = onDelete || $.noop; + this._onAssignChanged = onAssignChanged || $.noop; + } + CreateController.prototype = { + deleteUser: deleteUser, + changeAssign: changeAssign, + getUser: getUser + }; + + function changeAssign(value) { + this._user.assigned = value; + this._onAssignChanged(this._user); + } + + function deleteUser() { + this._onDelete(this._user); + } + + function getUser() { + return this._user; + } +})(); \ No newline at end of file diff --git a/js/usersList.js b/js/usersList.js new file mode 100644 index 0000000..341e4d6 --- /dev/null +++ b/js/usersList.js @@ -0,0 +1,103 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + "use strict"; + app.addModule("usersList", { + createUsersList: createUsersList + }); + + var arrayUtils = app.getModule("arrayUtils"); + + function createUsersList(usersList, onUserAdded, onUserDeleted, onAssignChanged) { + var controller = new CreateController(usersList, onUserAdded, onUserDeleted, onAssignChanged); + return createView(controller); + } + + function createView(controller) { + var userCreate = app.getModule("user").createUser; + var usersList = controller.getUsersList(); + + var $viewTemplate = $('\ +
    \ +
    \ + Sort by name:\ + \ + \ +
    \ + \ +
    ' + ); + + var $listContainer = $viewTemplate.find("ul"); + + $viewTemplate.find(".sortByUserNameAscending").on("click", function() { + controller.sortUsers("name", "ascending"); + }); + + $viewTemplate.find(".sortByUserNameDescending").on("click", function() { + controller.sortUsers("name", "descending"); + }); + + controller.addResetView(buildUsersList); + app.addMethod("usersList", "refreshView", buildUsersList); + + buildUsersList(); + function buildUsersList() { + $listContainer.empty(); + usersList.forEach(function (user) { + $listContainer.append(userCreate(user, controller.deleteUser.bind(controller), controller.onAssignChanged)); + }) + } + + return $viewTemplate; + } + + function CreateController(usersList, onUserAdded, onUserDeleted, onAssignChanged) { + this._usersList = usersList || []; + this._onUserAdded = onUserAdded || $.noop; + this._onUserDeleted = onUserDeleted || $.noop; + this.onAssignChanged = onAssignChanged || $.noop; + } + CreateController.prototype = { + addUser: addUser, + deleteUser: deleteUser, + checkEmailUnique: checkEmailUnique, + sortUsers: sortUsers, + getUsersList: getUsersList, + addResetView: addResetView + }; + + function addUser(newUser) { + if (this.checkEmailUnique(newUser)) { + this._usersList.push(newUser); + this.resetView(); + return true; + } + else { + alert("User with this email already exist"); + } + } + + function deleteUser(user) { + var index = this._usersList.indexOf(user); + this._onUserDeleted(this._usersList.splice(index, 1)[0]); + this.resetView(); + } + + function checkEmailUnique(user) { + return arrayUtils.findInArray(this._usersList, {email: user.email}); + } + + function sortUsers(field, direction) { + arrayUtils.sortArray(this._usersList, field, direction); + } + + function getUsersList() { + return this._usersList; + } + + function addResetView(resetView) { + this.resetView = resetView; + } +})(); \ No newline at end of file diff --git a/js/validateUtils.js b/js/validateUtils.js new file mode 100644 index 0000000..9401afa --- /dev/null +++ b/js/validateUtils.js @@ -0,0 +1,20 @@ +/** + * Created by AterStrix on 08.03.2017. + */ +(function () { + "use strict"; + app.addModule("validateUtils", { + validateRequired: validateRequired, + validateEmail: validateEmail + }); + + var emailValidationPattern = /\w+@\w+\.\w+/; + + function validateRequired(value) { + return value !== ""; + } + + function validateEmail(email) { + return emailValidationPattern.test(email); + } +})(); \ No newline at end of file From afaf59f14faf7af6b6529b4f287d1396b83d444c Mon Sep 17 00:00:00 2001 From: aterstrix Date: Fri, 10 Mar 2017 18:59:04 +0200 Subject: [PATCH 2/3] In progress. --- index.html | 1 + js/main.js | 4 +- js/task.js | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ js/tasksList.js | 105 +++++++++++++++++++++++++++++++++++++++++ js/usersList.js | 11 ++--- 5 files changed, 236 insertions(+), 8 deletions(-) diff --git a/index.html b/index.html index 59c399f..6d86a27 100644 --- a/index.html +++ b/index.html @@ -18,5 +18,6 @@

    Base template

    +
    \ No newline at end of file diff --git a/js/main.js b/js/main.js index cdce374..de7b36c 100644 --- a/js/main.js +++ b/js/main.js @@ -4,9 +4,9 @@ var users = []; $("h1").after(addUserForm.createAddUserForm(function (user) { users.push(user); - $(".addUser").after(usersList.createUsersList(users)); + usersList.refreshView(); return true; - })); + })).next().after(usersList.createUsersList(users)); })(); \ No newline at end of file diff --git a/js/task.js b/js/task.js index 5a2e6df..a8a07d0 100644 --- a/js/task.js +++ b/js/task.js @@ -1,3 +1,126 @@ /** * Created by AterStrix on 08.03.2017. */ +(function () { + app.addModule("task", { + createTask: createTask + }); + + function createTask(task, onDelete, onMoveTop, onMoveBottom, onComplete) { + var controller = new CreateController(task, onDelete, onMoveTop, onMoveBottom, onComplete); + return createView(controller); + } + + function createView(controller) { + var task = controller.getTask(); + + var $viewTemplate = $('\ +
  • \ +

    '+task.title+'

    \ +

    Create date\ + '+getFormattedDate(task.createDate)+' \ +

    \ +

    Assignd to '+ task.assignedUsers.length +' users

    \ +
    \ + \ + \ + \ +
    \ + \ +
  • ' + ); + + var $deleteButton = $viewTemplate.find(".deleteButton"); + var $moveTopButton = $viewTemplate.find(".moveTopButton"); + var $moveBottomButton = $viewTemplate.find(".moveBottomButton"); + var $completeButton = $viewTemplate.find(".completeButton"); + + setState(); + function setState(task) { + if (task.completed) { + $viewTemplate.addClass("completed"); + } + else if (task.active) { + $viewTemplate.addClass("active"); + } + } + + controller.addUpdateState(setState); + + $deleteButton.on("click", function() { + controller.deleteTask(); + }); + + $moveTopButton.on("click", function () { + controller.moveTop(); + }); + + $moveBottomButton.on("click", function () { + controller.moveBottom(); + }); + + $completeButton.on("click", function () { + $viewTemplate.addClass('completed'); + controller.completeTask(); + }); + + function getFormattedDate(date) { + return date.getDate() + "/" + date.getMonth() + "/" + date.getFullYear() + " " + + date.getHours() + ":" + date.getMinutes(); + } + + return $viewTemplate; + } + + function CreateController(task, onDelete, onMoveTop, onMoveBottom, onComplete, onActive) { + this._task = task || {}; + this._onDelete = onDelete || $.noop; + this._onMoveTop = onMoveTop || $.noop; + this._onMoveBottom = onMoveBottom || $.noop; + this._onComplete = onComplete || $.noop; + this._onActive = onActive || $.noop; + } + CreateController.prototype = { + deleteTask: deleteTask, + moveTop: moveTop, + moveBottom: moveBottom, + getTask: getTask, + activeTask: activeTask, + completeTask: completeTask, + addUpdateState: addUpdateState + }; + + function deleteTask() { + this._onDelete(this._task); + } + + function getTask() { + return this._task; + } + + function moveTop() { + this._onMoveTop(this._task); + } + + function moveBottom() { + this._onMoveBottom(this._task); + } + + function completeTask() { + this._task.completed = true; + this.updateState(this._task); + this._onComplete(this._task); + } + + function activeTask() { + if (!this._task.completed) { + this._task.active = true; + this.updateState(this._task); + this._onActive(this._task); + } + } + + function addUpdateState(method) { + this.updateState = method; + } +})(); \ No newline at end of file diff --git a/js/tasksList.js b/js/tasksList.js index 5a2e6df..2329354 100644 --- a/js/tasksList.js +++ b/js/tasksList.js @@ -1,3 +1,108 @@ /** * Created by AterStrix on 08.03.2017. */ +(function () { + "use strict"; + app.addModule("tasksList", { + createTasksList: createTasksList + }); + + var taskModule = app.getModule("task"); + var arrayUtils = app.getModule("arrayUtils"); + + function createTasksList(tasksList, onTaskDeleted, onTaskCompleted) { + var controller = new CreateController(tasksList, onTaskDeleted, onTaskCompleted); + return createView(controller); + } + + function createView(controller) { + var tasksList = controller.getTasksList(); + + var $viewTemplate = $('\ +
    \ +
    \ + Sort by name:\ + \ + \ +
    \ +
      \ +
      ' + ); + + var $listContainer = $viewTemplate.find("ul"); + + $viewTemplate.find(".sortByUserNameAscending").on("click", function() { + controller.sortUsers("name", "ascending"); + }); + + $viewTemplate.find(".sortByUserNameDescending").on("click", function() { + controller.sortUsers("name", "descending"); + }); + + controller.addResetView(buildTasksList); + app.addMethod("tasksList", "refreshView", buildTasksList); + + buildTasksList(); + function buildTasksList() { + $listContainer.empty(); + tasksList.forEach(function (user) { + $listContainer.append(taskModule.createTask(user, + controller.deleteTask.bind(controller), + controller.moveTop.bind(controller), + controller.moveBottom.bind(controller), + controller.completeTask.bind(controller) + )); + }) + } + + return $viewTemplate; + } + + function CreateController(tasksList, onTaskDeleted, onTaskCompleted) { + this._tasksList = tasksList || []; + this._onTaskDeleted = onTaskDeleted || $.noop; + this._onTaskCompleted = onTaskCompleted || $.noop; + } + CreateController.prototype = { + deleteTask: deleteTask, + sortTasks: sortTasks, + getTasksList: getTasksList, + moveTop: moveTop, + moveBottom: moveBottom, + completeTask: completeTask, + addResetView: addResetView + }; + + function deleteTask(task) { + var index = this._tasksList.indexOf(task); + this._onTaskDeleted(this._tasksList.splice(index, 1)[0]); + this.resetView(); + } + + function sortTasks(field, direction) { + arrayUtils.sortArray(this._tasksList, field, direction); + this.resetView(); + } + + function getTasksList() { + return this._tasksList; + } + + function moveTop() { + + } + + function moveBottom() { + + } + + function completeTask(task) { + var index = this._tasksList.indexOf(task); + task.completed = true; + this._onTaskCompleted(task); + } + + function addResetView(resetView) { + this.resetView = resetView; + } +})(); \ No newline at end of file diff --git a/js/usersList.js b/js/usersList.js index 341e4d6..d6ddabf 100644 --- a/js/usersList.js +++ b/js/usersList.js @@ -8,14 +8,14 @@ }); var arrayUtils = app.getModule("arrayUtils"); + var userModule = app.getModule("user"); - function createUsersList(usersList, onUserAdded, onUserDeleted, onAssignChanged) { - var controller = new CreateController(usersList, onUserAdded, onUserDeleted, onAssignChanged); + function createUsersList(usersList, onUserDeleted, onAssignChanged) { + var controller = new CreateController(usersList, onUserDeleted, onAssignChanged); return createView(controller); } function createView(controller) { - var userCreate = app.getModule("user").createUser; var usersList = controller.getUsersList(); var $viewTemplate = $('\ @@ -46,16 +46,15 @@ function buildUsersList() { $listContainer.empty(); usersList.forEach(function (user) { - $listContainer.append(userCreate(user, controller.deleteUser.bind(controller), controller.onAssignChanged)); + $listContainer.append(userModule.createUser(user, controller.deleteUser.bind(controller), controller.onAssignChanged)); }) } return $viewTemplate; } - function CreateController(usersList, onUserAdded, onUserDeleted, onAssignChanged) { + function CreateController(usersList, onUserDeleted, onAssignChanged) { this._usersList = usersList || []; - this._onUserAdded = onUserAdded || $.noop; this._onUserDeleted = onUserDeleted || $.noop; this.onAssignChanged = onAssignChanged || $.noop; } From 0b52e683061fae6d0218209009f539b0feef7ede Mon Sep 17 00:00:00 2001 From: AterStrix Date: Sat, 11 Mar 2017 00:26:59 +0200 Subject: [PATCH 3/3] Added TODO List --- css/main.css | 60 ++++++++++++++++ index.html | 4 ++ js/TODOList.js | 167 +++++++++++++++++++++++++++++++++++++++++++- js/addTaskForm.js | 91 ++++++++++++++++++++++++ js/addUserForm.js | 25 +++---- js/arrayUtils.js | 2 +- js/main.js | 78 ++++++++++++++++++--- js/task.js | 57 ++++++++------- js/tasksList.js | 74 ++++++++++++++------ js/user.js | 11 ++- js/usersList.js | 39 ++++------- js/validateUtils.js | 7 +- 12 files changed, 514 insertions(+), 101 deletions(-) diff --git a/css/main.css b/css/main.css index 367bfaa..6063c93 100644 --- a/css/main.css +++ b/css/main.css @@ -7,4 +7,64 @@ } .mainTitle .text { vertical-align:middle; +} +.todo-list { + overflow: hidden; + width: 70%; + margin: 0 auto; +} +.todo-list .userManagement, .todo-list .taskManagement{ + float: left; + width:40%; + box-sizing: border-box; + border: 2px solid #ccc; + padding: 10px; + margin: 5%; +} + +.todo-list .addUser input, +.todo-list .addTask input { + display: block; + margin:0 0 5px; +} + +.todo-list input[type="text"], +.todo-list textarea { + width: 100%; +} + +.todo-list p, +.todo-list h2{ + margin: 0; + padding: 0 0 5px; +} + +.todo-list ul { + margin: 0; + padding: 0; +} + +.todo-list li { + list-style: none; + padding: 5px; + margin: 5px 0; + border: 2px solid #ccc;; +} + +.todo-list .user labl { + display: block; + padding: 0 0 5px; + +} + +.todo-list .complete-btn { + margin: 5px 0 0; +} + +.todo-list .completed { + background: #66FF66; +} + +.todo-list .active { + background: #c0c0c0; } \ No newline at end of file diff --git a/index.html b/index.html index 6d86a27..0ae206d 100644 --- a/index.html +++ b/index.html @@ -8,8 +8,12 @@ + + + + diff --git a/js/TODOList.js b/js/TODOList.js index 1eda0bd..d43d22e 100644 --- a/js/TODOList.js +++ b/js/TODOList.js @@ -3,5 +3,170 @@ */ (function () { "use strict"; - app.addModule("TODOList", {}); + app.addModule("TODOList", { + createTODOList: createTODOList + }); + var addTaskForm = app.getModule("addTaskForm"); + var addUserForm = app.getModule("addUserForm"); + var usersList = app.getModule("usersList"); + var tasksList = app.getModule("tasksList"); + var arrayUtils = app.getModule("arrayUtils"); + + function createTODOList(users, tasks) { + var controller = new CreateController(users, tasks); + return createView(controller); + } + + function createView(controller) { + var $viewTemplate = $('\ +
      \ +
      \ +
      \ +
      ' + ); + + $viewTemplate.find(".userManagement").append( + addUserForm.createAddUserForm(controller.addUser.bind(controller)) + ).append( + usersList.createUsersList( + controller.getUsers(), + controller.userDeleted.bind(controller), + controller.userAssignChange.bind(controller) + ) + ); + $viewTemplate.find(".taskManagement").append( + addTaskForm.createAddTaskForm(controller.addTask.bind(controller)) + ).append( + tasksList.createTasksList( + controller.getTasks(), + controller.taskDeleted.bind(controller), + controller.taskCompleted.bind(controller), + controller.taskActive.bind(controller) + ) + ); + + controller.addResetView(function () { + tasksList.refreshView(); + usersList.refreshView(); + }); + + return $viewTemplate; + } + + function CreateController(users, tasks) { + this._users = users; + this._tasks = tasks; + this._activeTask = null; + } + CreateController.prototype = { + addUser: addUser, + addTask: addTask, + userAssignChange: userAssignChange, + addResetView: addResetView, + getUsers: getUsers, + getTasks: getTasks, + userDeleted: userDeleted, + taskDeleted: taskDeleted, + taskActive: taskActive, + taskCompleted: taskCompleted + }; + + function addUser(user) { + if (!arrayUtils.findInArray(this.getUsers(), {email: user.email})) { + this.getUsers().push(user); + this.resetView(); + return true; + } + else { + alert('User with this email already exist'); + } + return false; + } + + function addTask(task) { + if (!arrayUtils.findInArray(this.getTasks(), {id: task.id})) { + this.getTasks().push(task); + this.resetView(); + return true; + } + else { + alert("Task with this ID already exist"); + } + return false; + } + + function getUsers() { + return this._users; + } + + function getTasks() { + return this._tasks; + } + + function userAssignChange(user, value) { + if (this._activeTask) { + user.assigned = value; + if (value) { + user.assignedTo.push(this._activeTask.id); + this._activeTask.assignedTo.push(user.email); + } + else { + user.assignedTo.splice(user.assignedTo.indexOf(this._activeTask.id, 1)); + this._activeTask.assignedTo.splice(this._activeTask.assignedTo.indexOf(user.email), 1); + } + } + this.resetView(); + } + + function userDeleted(user) { + var that = this; + user.assignedTo.forEach(function (taskId) { + var task = arrayUtils.findInArray(that.getTasks(), {id: taskId}); + task.assignedTo.splice(task.assignedTo.indexOf(user.email), 1); + }); + this.resetView(); + } + + function taskDeleted(task) { + var that = this; + task.assignedTo.forEach(function (userEmail) { + var user = arrayUtils.findInArray(that.getUsers(), {email: userEmail}); + user.assignedTo.splice(user.assignedTo.indexOf(task.id), 1); + if (that._activeTask === task) { + user.assigned = false; + } + }); + if (this._activeTask === task) { + this._activeTask = null; + } + this.resetView(); + } + + function taskActive(task) { + if (this._activeTask) + this._activeTask.active = false; + task.active = true; + this._activeTask = task; + this.getUsers().forEach(function(user) { + user.assigned = !!~task.assignedTo.indexOf(user.email); + }); + this.resetView(); + } + + function taskCompleted(task) { + var that = this; + task.assignedTo.forEach(function (userEmail) { + var user = arrayUtils.findInArray(that.getUsers(), {email: userEmail}); + user.assignedTo.splice(user.assignedTo.indexOf(task.id), 1); + if (that._activeTask === task) { + user.assigned = false; + } + }); + task.assignedTo = []; + this.resetView(); + } + + function addResetView(resetView) { + this.resetView = resetView; + } })(); \ No newline at end of file diff --git a/js/addTaskForm.js b/js/addTaskForm.js index d85c04a..96e8e6f 100644 --- a/js/addTaskForm.js +++ b/js/addTaskForm.js @@ -2,5 +2,96 @@ * Created by AterStrix on 08.03.2017. */ (function () { + "use strict"; + app.addModule("addTaskForm", { + createAddTaskForm: createAddTaskForm + }); + var validateUtils = app.getModule("validateUtils"); + + function createAddTaskForm(onAddTask) { + var controller = new CreateController(onAddTask); + return createView(controller); + } + + function createView(controller) { + var $viewTemplate = $('\ +
      \ + \ + \ + \ + \ +
      ' + ); + + var $taskTitle = $viewTemplate.find(".taskTitle"); + var $taskDescription = $viewTemplate.find(".taskDescription"); + var $taskId = $viewTemplate.find(".taskId"); + + $viewTemplate.find(".addTaskButton").on("click", function() { + controller.addTask($taskTitle.val(), $taskDescription.val(), $taskId.val()); + }); + + controller.addResetView(function () { + $taskTitle.val(""); + $taskDescription.val(""); + $taskId.val(""); + }); + + return $viewTemplate; + } + + function getTaskModel() { + return { + title: "", + description: "", + id: "", + createDate: new Date(), + active: false, + completed: false, + assignedTo: [] + } + } + + function CreateController(onAddTask) { + this._onAddTask = onAddTask; + this._taskModel = getTaskModel(); + } + CreateController.prototype = { + addTask: addTask, + validateForm: validateForm, + addResetView: addResetView + }; + + function addTask(taskTitle, taskDescription, taskId) { + this._taskModel.title = taskTitle; + this._taskModel.description = taskDescription; + this._taskModel.id = taskId; + this._taskModel.createDate = new Date(); + if (this.validateForm() && this._onAddTask(this._taskModel)) { + this._taskModel = getTaskModel(); + this.resetView(); + } + } + + function validateForm() { + var errorMessage = ""; + if (!validateUtils.validateRequired(this._taskModel.title)) { + errorMessage += "Field Task Title is required\n"; + } + if (!validateUtils.validateRequired(this._taskModel.description)) { + errorMessage += "Field Task Description is required\n"; + } + if (!validateUtils.validateRequired(this._taskModel.id)) { + errorMessage += "Field Task ID is required\n"; + } + if (errorMessage) { + alert(errorMessage); + } + return !errorMessage; + } + + function addResetView(resetView) { + this.resetView = resetView; + } })(); \ No newline at end of file diff --git a/js/addUserForm.js b/js/addUserForm.js index 5b8e068..b1d2100 100644 --- a/js/addUserForm.js +++ b/js/addUserForm.js @@ -38,13 +38,19 @@ return $viewTemplate; } - function CreateController(onAddUser) { - this._onAddUser = onAddUser; - this._userModel = { + function getUserModel() { + return { name: "", - email: "" + email: "", + assigned: false, + assignedTo: [] } } + + function CreateController(onAddUser) { + this._onAddUser = onAddUser; + this._userModel = getUserModel(); + } CreateController.prototype = { addUser: addUser, validateForm: validateForm, @@ -52,15 +58,10 @@ }; function addUser(userName, userEmail) { - this._userModel = { - name: userName, - email: userEmail - }; + this._userModel.name = userName; + this._userModel.email = userEmail; if (this.validateForm() && this._onAddUser(this._userModel)) { - this._userModel = { - name: "", - email: "" - }; + this._userModel = getUserModel(); this.resetView(); } } diff --git a/js/arrayUtils.js b/js/arrayUtils.js index 55f7544..6bb22a7 100644 --- a/js/arrayUtils.js +++ b/js/arrayUtils.js @@ -21,7 +21,7 @@ return sortText(a[field], b[field]); }) } - if (direction === 'ascending') { + if (direction === 'descending') { array.reverse(); } } diff --git a/js/main.js b/js/main.js index de7b36c..cead86f 100644 --- a/js/main.js +++ b/js/main.js @@ -1,12 +1,74 @@ (function () { - var addUserForm = app.getModule("addUserForm"); - var usersList = app.getModule("usersList"); - var users = []; - $("h1").after(addUserForm.createAddUserForm(function (user) { - users.push(user); - usersList.refreshView(); - return true; - })).next().after(usersList.createUsersList(users)); + var TODO_List = app.getModule("TODOList"); + $("h1").after(TODO_List.createTODOList([ + { + name: "asadsad asdas ", + email: "asdasd@asdaf.ds", + assigned: false, + assignedTo: [] + }, + { + name: "sarggfhf gh fgh", + email: "asd2ASD@asd.ds", + assigned: false, + assignedTo: [] + }, + { + name: "asd1 12 312", + email: "asdkjash@asd.aadsd", + assigned: false, + assignedTo: [] + }, + { + name: "asd 1231 ", + email: "lkajf@asdfsd.sa", + assigned: false, + assignedTo: [] + }, + { + name: "13214 234 324 ", + email: "ad@dsa.asd", + assigned: false, + assignedTo: [] + } + ],[ + { + title: "asd 1", + description: "asdasdas asdsadasd asd as ", + id: "asda d1231", + active: false, + createDate: new Date(2000, 1, 1), + completed: false, + assignedTo: [] + }, + { + title: "asd 2", + description: "asd asdas dsad asdasd", + id: "assa das123", + active: false, + createDate: new Date(2100, 1, 1), + completed: false, + assignedTo: [] + }, + { + title: "asd 3", + description: "asd asdsad asd ", + id: "asdasd 2", + createDate: new Date(1900, 1, 1), + active: false, + completed: false, + assignedTo: [] + }, + { + title: "asd 4", + description: "asd asdsa sad sad asds", + id: "sad 1", + active: false, + createDate: new Date(1800, 1, 1), + completed: false, + assignedTo: [] + } + ])); })(); \ No newline at end of file diff --git a/js/task.js b/js/task.js index a8a07d0..7b85e3d 100644 --- a/js/task.js +++ b/js/task.js @@ -6,8 +6,8 @@ createTask: createTask }); - function createTask(task, onDelete, onMoveTop, onMoveBottom, onComplete) { - var controller = new CreateController(task, onDelete, onMoveTop, onMoveBottom, onComplete); + function createTask(task, onDelete, onMoveTop, onMoveBottom, onComplete, onActive) { + var controller = new CreateController(task, onDelete, onMoveTop, onMoveBottom, onComplete, onActive); return createView(controller); } @@ -20,13 +20,13 @@

      Create date\ '+getFormattedDate(task.createDate)+' \

      \ -

      Assignd to '+ task.assignedUsers.length +' users

      \ +

      Assignd to '+ task.assignedTo.length +' users

      \
      \ \ \ \
      \ - \ + \ ' ); @@ -35,38 +35,44 @@ var $moveBottomButton = $viewTemplate.find(".moveBottomButton"); var $completeButton = $viewTemplate.find(".completeButton"); - setState(); - function setState(task) { - if (task.completed) { - $viewTemplate.addClass("completed"); - } - else if (task.active) { - $viewTemplate.addClass("active"); - } + if (task.completed) { + $viewTemplate.addClass("completed"); + } + else if (task.active) { + $viewTemplate.addClass("active"); } - controller.addUpdateState(setState); - - $deleteButton.on("click", function() { + $deleteButton.on("click", function(e) { + e.stopPropagation(); controller.deleteTask(); }); - $moveTopButton.on("click", function () { + $moveTopButton.on("click", function (e) { + e.stopPropagation(); controller.moveTop(); }); - $moveBottomButton.on("click", function () { + $moveBottomButton.on("click", function (e) { + e.stopPropagation(); controller.moveBottom(); }); - $completeButton.on("click", function () { - $viewTemplate.addClass('completed'); + $completeButton.on("click", function (e) { + e.stopPropagation(); controller.completeTask(); }); + $viewTemplate.on("click", function(e) { + e.stopPropagation(); + controller.activeTask(); + }); + function getFormattedDate(date) { - return date.getDate() + "/" + date.getMonth() + "/" + date.getFullYear() + " " + - date.getHours() + ":" + date.getMinutes(); + return date.getDate() + "/" + + (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "/" + + date.getFullYear() + " " + + (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":" + + (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()); } return $viewTemplate; @@ -79,6 +85,7 @@ this._onMoveBottom = onMoveBottom || $.noop; this._onComplete = onComplete || $.noop; this._onActive = onActive || $.noop; + this._updateState = $.noop; } CreateController.prototype = { deleteTask: deleteTask, @@ -107,20 +114,16 @@ } function completeTask() { - this._task.completed = true; - this.updateState(this._task); this._onComplete(this._task); } function activeTask() { - if (!this._task.completed) { - this._task.active = true; - this.updateState(this._task); + if (!this._task.completed && !this._task.active) { this._onActive(this._task); } } function addUpdateState(method) { - this.updateState = method; + this._updateState = method; } })(); \ No newline at end of file diff --git a/js/tasksList.js b/js/tasksList.js index 2329354..bc4cd5d 100644 --- a/js/tasksList.js +++ b/js/tasksList.js @@ -10,8 +10,8 @@ var taskModule = app.getModule("task"); var arrayUtils = app.getModule("arrayUtils"); - function createTasksList(tasksList, onTaskDeleted, onTaskCompleted) { - var controller = new CreateController(tasksList, onTaskDeleted, onTaskCompleted); + function createTasksList(tasksList, onTaskDeleted, onTaskCompleted, onTaskActive) { + var controller = new CreateController(tasksList, onTaskDeleted, onTaskCompleted, onTaskActive); return createView(controller); } @@ -22,21 +22,32 @@
      \
      \ Sort by name:\ - \ - \ + \ + \
      \ + Sort by date:\ + \ + \
        \
        ' ); var $listContainer = $viewTemplate.find("ul"); - $viewTemplate.find(".sortByUserNameAscending").on("click", function() { - controller.sortUsers("name", "ascending"); + $viewTemplate.find(".sortByTitleAscending").on("click", function() { + controller.sortTasks("title", "ascending"); }); - $viewTemplate.find(".sortByUserNameDescending").on("click", function() { - controller.sortUsers("name", "descending"); + $viewTemplate.find(".sortByTitleDescending").on("click", function() { + controller.sortTasks("title", "descending"); + }); + + $viewTemplate.find(".sortByDateAscending").on("click", function() { + controller.sortTasks("createDate", "ascending"); + }); + + $viewTemplate.find(".sortByDateDescending").on("click", function() { + controller.sortTasks("createDate", "descending"); }); controller.addResetView(buildTasksList); @@ -50,7 +61,8 @@ controller.deleteTask.bind(controller), controller.moveTop.bind(controller), controller.moveBottom.bind(controller), - controller.completeTask.bind(controller) + controller.completeTask.bind(controller), + controller.activeTask.bind(controller) )); }) } @@ -58,10 +70,11 @@ return $viewTemplate; } - function CreateController(tasksList, onTaskDeleted, onTaskCompleted) { + function CreateController(tasksList, onTaskDeleted, onTaskCompleted, onTaskActive) { this._tasksList = tasksList || []; this._onTaskDeleted = onTaskDeleted || $.noop; this._onTaskCompleted = onTaskCompleted || $.noop; + this._onTaskActive = onTaskActive || $.noop; } CreateController.prototype = { deleteTask: deleteTask, @@ -70,17 +83,18 @@ moveTop: moveTop, moveBottom: moveBottom, completeTask: completeTask, + activeTask: activeTask, addResetView: addResetView }; function deleteTask(task) { - var index = this._tasksList.indexOf(task); - this._onTaskDeleted(this._tasksList.splice(index, 1)[0]); + var index = this.getTasksList().indexOf(task); + this._onTaskDeleted(this.getTasksList().splice(index, 1)[0]); this.resetView(); } function sortTasks(field, direction) { - arrayUtils.sortArray(this._tasksList, field, direction); + arrayUtils.sortArray(this.getTasksList(), field, direction); this.resetView(); } @@ -88,18 +102,38 @@ return this._tasksList; } - function moveTop() { - + function moveTop(task) { + if (!task.completed) { + var index = this.getTasksList().indexOf(task); + if (index > 0) { + this._tasksList.splice(index - 1, 0, this._tasksList.splice(index, 1)[0]); + this.resetView(); + } + } } - function moveBottom() { - + function moveBottom(task) { + if (!task.completed) { + var index = this.getTasksList().indexOf(task); + if (index < this.getTasksList().length - 1) { + this._tasksList.splice(index + 1, 0, this._tasksList.splice(index, 1)[0]); + this.resetView(); + } + } } function completeTask(task) { - var index = this._tasksList.indexOf(task); - task.completed = true; - this._onTaskCompleted(task); + if (!task.completed) { + var index = this.getTasksList().indexOf(task); + this.getTasksList().push(this.getTasksList().splice(index, 1)[0]); + task.completed = true; + this._onTaskCompleted(task); + this.resetView(); + } + } + + function activeTask(task) { + this._onTaskActive(task); } function addResetView(resetView) { diff --git a/js/user.js b/js/user.js index 2cc5507..109c117 100644 --- a/js/user.js +++ b/js/user.js @@ -6,8 +6,8 @@ createUser: createUser }); - function createUser(user, onDelete, onAssignChanged) { - var controller = new CreateController(user, onDelete, onAssignChanged); + function createUser(user, onDelete, onAssignChange) { + var controller = new CreateController(user, onDelete, onAssignChange); return createView(controller); } @@ -39,10 +39,10 @@ return $viewTemplate; } - function CreateController(user, onDelete, onAssignChanged) { + function CreateController(user, onDelete, onAssignChange) { this._user = user || {}; this._onDelete = onDelete || $.noop; - this._onAssignChanged = onAssignChanged || $.noop; + this._onAssignChange = onAssignChange || $.noop; } CreateController.prototype = { deleteUser: deleteUser, @@ -51,8 +51,7 @@ }; function changeAssign(value) { - this._user.assigned = value; - this._onAssignChanged(this._user); + this._onAssignChange(this._user, value); } function deleteUser() { diff --git a/js/usersList.js b/js/usersList.js index d6ddabf..5469077 100644 --- a/js/usersList.js +++ b/js/usersList.js @@ -10,8 +10,8 @@ var arrayUtils = app.getModule("arrayUtils"); var userModule = app.getModule("user"); - function createUsersList(usersList, onUserDeleted, onAssignChanged) { - var controller = new CreateController(usersList, onUserDeleted, onAssignChanged); + function createUsersList(usersList, onUserDeleted, onAssignChange) { + var controller = new CreateController(usersList, onUserDeleted, onAssignChange); return createView(controller); } @@ -22,8 +22,8 @@
        \
        \ Sort by name:\ - \ - \ + \ + \
        \
          \
          ' @@ -31,11 +31,11 @@ var $listContainer = $viewTemplate.find("ul"); - $viewTemplate.find(".sortByUserNameAscending").on("click", function() { + $viewTemplate.find(".sortByNameAscending").on("click", function() { controller.sortUsers("name", "ascending"); }); - $viewTemplate.find(".sortByUserNameDescending").on("click", function() { + $viewTemplate.find(".sortByNameDescending").on("click", function() { controller.sortUsers("name", "descending"); }); @@ -46,20 +46,19 @@ function buildUsersList() { $listContainer.empty(); usersList.forEach(function (user) { - $listContainer.append(userModule.createUser(user, controller.deleteUser.bind(controller), controller.onAssignChanged)); + $listContainer.append(userModule.createUser(user, controller.deleteUser.bind(controller), controller.onAssignChange)); }) } return $viewTemplate; } - function CreateController(usersList, onUserDeleted, onAssignChanged) { + function CreateController(usersList, onUserDeleted, onAssignChange) { this._usersList = usersList || []; this._onUserDeleted = onUserDeleted || $.noop; - this.onAssignChanged = onAssignChanged || $.noop; + this.onAssignChange = onAssignChange || $.noop; } CreateController.prototype = { - addUser: addUser, deleteUser: deleteUser, checkEmailUnique: checkEmailUnique, sortUsers: sortUsers, @@ -67,29 +66,19 @@ addResetView: addResetView }; - function addUser(newUser) { - if (this.checkEmailUnique(newUser)) { - this._usersList.push(newUser); - this.resetView(); - return true; - } - else { - alert("User with this email already exist"); - } - } - function deleteUser(user) { - var index = this._usersList.indexOf(user); - this._onUserDeleted(this._usersList.splice(index, 1)[0]); + var index = this.getUsersList().indexOf(user); + this._onUserDeleted(this.getUsersList().splice(index, 1)[0]); this.resetView(); } function checkEmailUnique(user) { - return arrayUtils.findInArray(this._usersList, {email: user.email}); + return arrayUtils.findInArray(this.getUsersList(), {email: user.email}); } function sortUsers(field, direction) { - arrayUtils.sortArray(this._usersList, field, direction); + arrayUtils.sortArray(this.getUsersList(), field, direction); + this.resetView(); } function getUsersList() { diff --git a/js/validateUtils.js b/js/validateUtils.js index 9401afa..f019e5c 100644 --- a/js/validateUtils.js +++ b/js/validateUtils.js @@ -5,7 +5,8 @@ "use strict"; app.addModule("validateUtils", { validateRequired: validateRequired, - validateEmail: validateEmail + validateEmail: validateEmail, + validateUnique: validateUnique }); var emailValidationPattern = /\w+@\w+\.\w+/; @@ -17,4 +18,8 @@ function validateEmail(email) { return emailValidationPattern.test(email); } + + function validateUnique(array, item, field) { + + } })(); \ No newline at end of file