-
Notifications
You must be signed in to change notification settings - Fork 9
Homework#5 [Done] #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 7 commits
9a9b86e
6aa360f
de5bc51
cbf5505
907ee15
7e372ce
2598a40
f8b220d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
index_copy.js |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | ||
<link | ||
href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600" | ||
rel="stylesheet" | ||
/> | ||
<link rel="stylesheet" href="style.css" /> | ||
<title>To-Do App</title> | ||
</head> | ||
<body> | ||
<main> | ||
<section class="application"> | ||
<div class="application__title"><span>To-Do List</span></div> | ||
<form class="form-group"> | ||
<div class="input-container"> | ||
<label class="input-label" for="input-text"> | ||
<span>Type a task</span> | ||
<input | ||
type="text" | ||
class="input-text" | ||
id="input-text" | ||
placeholder="What to do?" | ||
/> | ||
<span>Set deadline</span> | ||
<select name="Deadline" id="deadline"> | ||
<option value="no deadline">no deadline</option> | ||
<option value="tomorrow">tomorrow</option> | ||
<option value="next week">next week</option> | ||
</select> | ||
<button class="submit-btn">Add</button> | ||
</label> | ||
</div> | ||
<div class="clear-container"> | ||
<button class="clear-btn">Clear tasks</button> | ||
</div> | ||
<div class="search-container"> | ||
<label for="filter" class="filter-label"> | ||
<span>Filter to-do's</span> | ||
<select name="Filter" id="filter"> | ||
<option value="no filter">no filter</option> | ||
<option value="no deadline">Deadline: no deadline</option> | ||
<option value="tomorrow">Deadline: tomorrow</option> | ||
<option value="next week">Deadline: next week</option> | ||
<option value="undone">Is done: undone</option> | ||
<option value="done">Is done: done</option> | ||
</select> | ||
<button class="filter-btn"> | ||
<i class="fas fa-filter"></i> | ||
</button> | ||
</label> | ||
</div> | ||
</form> | ||
<ul class="collection"> | ||
<!-- <li class="collection__item" id="item-0"> | ||
<span class="text">Lorem ipsum dolor</span> | ||
<span class="deadline">Deadline: tomorrow</span> | ||
<div class="icons"> | ||
<i class="far fa-circle"></i> | ||
<i class="fas fa-backspace"></i> | ||
</div> | ||
</li> | ||
<li class="collection__item" id="item-0"> | ||
<span>Lorem ipsum dolor</span> | ||
<div class="icons"> | ||
<i class="far fa-check-circle"></i> | ||
<i class="fas fa-backspace"></i> | ||
</div> | ||
</li> | ||
<li class="collection__item" id="item-0"> | ||
<span>Lorem ipsum dolor</span> | ||
<div class="icons"> | ||
<i class="far fa-circle"></i> | ||
<i class="fas fa-backspace"></i> | ||
</div> | ||
</li> --> | ||
</ul> | ||
</section> | ||
</main> | ||
<script src="index.js"></script> | ||
<script src="https://kit.fontawesome.com/a863ebaea0.js"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,253 @@ | ||
var UIController = (function() { | ||
var DOMStrings; | ||
DOMStrings = { | ||
taskInput: '.input-text', | ||
deadlineInput: '#deadline', | ||
submitBtn: '.submit-btn', | ||
filterInput: '#filter', | ||
filterBtn: '.filter-btn', | ||
uncheckedBtn: 'far fa-circle', | ||
checkedBtn: 'far fa-check-circle', | ||
deleteBtn: 'fas fa-backspace', | ||
taskList: '.collection', | ||
clearBtn: '.clear-btn' | ||
}; | ||
|
||
return { | ||
getInput: function() { | ||
return { | ||
text: document.querySelector(DOMStrings.taskInput).value, | ||
deadline: document.querySelector(DOMStrings.deadlineInput).value, | ||
filterValue: document.querySelector(DOMStrings.filterInput).value | ||
}; | ||
}, | ||
getDOMStrings: function() { | ||
return DOMStrings; | ||
}, | ||
deleteListItem: function(selectorID) { | ||
var element; | ||
element = document.querySelector(`#${selectorID}`); | ||
element.parentNode.removeChild(element); | ||
}, | ||
toggleTask: function(icon) { | ||
if (icon.className === DOMStrings.checkedBtn) { | ||
icon.className = DOMStrings.uncheckedBtn; | ||
} else if (icon.className === DOMStrings.uncheckedBtn) { | ||
icon.className = DOMStrings.checkedBtn; | ||
} | ||
}, | ||
filterTasks: function(tasks) { | ||
var filterValue, filteredTasks, taskList; | ||
var html = ''; | ||
filterValue = document.querySelector(DOMStrings.filterInput).value; | ||
taskList = document.querySelector(DOMStrings.taskList); | ||
|
||
filteredTasks = tasks.filter(function(task) { | ||
return task.deadline == filterValue || task.isDone == filterValue; | ||
}); | ||
filteredTasks.forEach(function(task) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move this logic to functions |
||
html += ` | ||
<li class="collection__item" id="item-${task.id}"> | ||
<span class="text">${task.text}</span> | ||
<div class="icons"> | ||
<i class="${task.iconClass}"></i> | ||
<i class="fas fa-backspace"></i> | ||
</div> | ||
<span class="deadline">Deadline: ${task.deadline}</span> | ||
</li> | ||
`; | ||
}); | ||
taskList.innerHTML = html; | ||
}, | ||
clearTasks: function() { | ||
document.querySelector(DOMStrings.taskList).innerHTML = ''; | ||
}, | ||
clearFields: function() { | ||
document.querySelector(DOMStrings.taskInput).value = ''; | ||
document.querySelector(DOMStrings.deadlineInput).value = 'no deadline'; | ||
document.querySelector(DOMStrings.taskInput).focus(); | ||
} | ||
}; | ||
})(); | ||
|
||
var storageController = (function(UICtrl) { | ||
var Task, tasks, DOM; | ||
DOM = UICtrl.getDOMStrings(); | ||
|
||
Task = function(id, text, deadline) { | ||
this.id = id; | ||
this.text = text; | ||
this.deadline = deadline; | ||
this.isDone = 'undone'; | ||
this.iconClass = DOM.uncheckedBtn; | ||
}; | ||
Task.prototype.toggleState = function() { | ||
if (this.isDone === 'undone') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move strings |
||
this.isDone = 'done'; | ||
this.iconClass = DOM.checkedBtn; | ||
} else if (this.isDone === 'done') { | ||
this.isDone = 'undone'; | ||
this.iconClass = DOM.uncheckedBtn; | ||
} | ||
}; | ||
if ( | ||
localStorage.getItem('tasks') === null || | ||
localStorage.getItem('tasks') === '' | ||
) { | ||
tasks = []; | ||
} else { | ||
tasks = JSON.parse(localStorage.getItem('tasks')); | ||
} | ||
return { | ||
getFromLS: function() { | ||
return tasks; | ||
}, | ||
addTask: function(text, deadline) { | ||
var newTask, ID; | ||
if (tasks.length > 0) ID = tasks[tasks.length - 1].id + 1; | ||
else ID = 0; | ||
newTask = new Task(ID, text, deadline); | ||
return newTask; | ||
}, | ||
addToLS: function(task) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why both functions - There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do that, valuable suggestion, should've separated the logic |
||
tasks.push(task); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, will fix that |
||
localStorage.setItem('tasks', JSON.stringify(tasks)); | ||
}, | ||
deleteFromLS: function(id) { | ||
var ids, index; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again - I don't think |
||
ids = tasks.map(function(current) { | ||
return current.id; | ||
}); | ||
index = ids.indexOf(id); | ||
if (index !== -1) { | ||
tasks.splice(index, 1); | ||
} | ||
localStorage.setItem('tasks', JSON.stringify(tasks)); | ||
}, | ||
toggleTask: function(id) { | ||
var ids, index; | ||
ids = tasks.map(function(current) { | ||
return current.id; | ||
}); | ||
index = ids.indexOf(id); | ||
if (index !== -1) { | ||
Task.prototype.toggleState.call(tasks[index]); | ||
} | ||
localStorage.setItem('tasks', JSON.stringify(tasks)); | ||
}, | ||
clearLS: function() { | ||
tasks = []; | ||
localStorage.setItem('tasks', []); | ||
} | ||
}; | ||
})(UIController); | ||
|
||
var controller = (function(UICtrl, storageCtrl) { | ||
var DOM = UICtrl.getDOMStrings(); | ||
var setUpEventListeners = function() { | ||
document.addEventListener('DOMContentLoaded', ctrlDisplayTasks); | ||
document | ||
.querySelector(DOM.submitBtn) | ||
.addEventListener('click', ctrlAddTask); | ||
document.addEventListener('keypress', function(event) { | ||
if (event.keyCode === 13 || event.which === 13) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move keycode There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, thanks! |
||
ctrlAddTask(); | ||
event.preventDefault(); | ||
} | ||
}); | ||
document | ||
.querySelector(DOM.taskList) | ||
.addEventListener('click', ctrlDeleteTask); | ||
document | ||
.querySelector(DOM.taskList) | ||
.addEventListener('click', ctrlToggleTask); | ||
document | ||
.querySelector(DOM.filterBtn) | ||
.addEventListener('click', ctrlFilterTasks); | ||
document | ||
.querySelector(DOM.clearBtn) | ||
.addEventListener('click', ctrlClearTasks); | ||
}; | ||
var ctrlDisplayTasks = function() { | ||
var tasks, taskList; | ||
var html = ''; | ||
tasks = storageCtrl.getFromLS(); | ||
taskList = document.querySelector(DOM.taskList); | ||
tasks.forEach(function(task) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use just |
||
html += ` | ||
<li class="collection__item" id="item-${task.id}"> | ||
<span class="text">${task.text}</span> | ||
<div class="icons"> | ||
<i class="${task.iconClass}"></i> | ||
<i class="fas fa-backspace"></i> | ||
</div> | ||
<span class="deadline">Deadline: ${task.deadline}</span> | ||
</li> | ||
`; | ||
}); | ||
taskList.innerHTML = html; | ||
}; | ||
var ctrlAddTask = function() { | ||
var input, newTask; | ||
event.preventDefault(); | ||
input = UICtrl.getInput(); | ||
if (input.text !== '') { | ||
newTask = storageCtrl.addTask(input.text, input.deadline, input.state); | ||
storageCtrl.addToLS(newTask); | ||
ctrlDisplayTasks(); | ||
UICtrl.clearFields(); | ||
} | ||
}; | ||
var ctrlDeleteTask = function(event) { | ||
var itemID, splitID, ID; | ||
if (event.target.className === DOM.deleteBtn) { | ||
itemID = event.target.parentNode.parentNode.id; | ||
} | ||
if (itemID) { | ||
splitID = itemID.split('-'); | ||
ID = +splitID[1]; | ||
storageCtrl.deleteFromLS(ID); | ||
UICtrl.deleteListItem(itemID); | ||
} | ||
}; | ||
var ctrlToggleTask = function(event) { | ||
var itemID, splitID, ID, icon; | ||
if (event.target.className === DOM.uncheckedBtn || DOM.checkedBtn) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you wanna check that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In current case, all I want to do is to check if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, it's correct, but I meant that your condition isn't correct - try in console There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now I see. To be correct, I should've done code like this, I suppose: |
||
itemID = event.target.parentNode.parentNode.id; | ||
icon = event.target; | ||
} | ||
if (itemID) { | ||
splitID = itemID.split('-'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move this logic to separated function |
||
type = splitID[0]; | ||
ID = +splitID[1]; | ||
storageCtrl.toggleTask(ID); | ||
UICtrl.toggleTask(icon); | ||
} | ||
}; | ||
var ctrlFilterTasks = function() { | ||
var tasks, filterValue, DOM; | ||
DOM = UICtrl.getDOMStrings(); | ||
tasks = storageCtrl.getFromLS(); | ||
filterValue = document.querySelector(DOM.filterInput).value; | ||
if (filterValue === 'no filter') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move |
||
ctrlDisplayTasks(); | ||
} else { | ||
UICtrl.filterTasks(tasks); | ||
} | ||
event.preventDefault(); | ||
}; | ||
var ctrlClearTasks = function() { | ||
event.preventDefault(); | ||
storageCtrl.clearLS(); | ||
UICtrl.clearTasks(); | ||
document.querySelector(DOM.filterInput).value = 'no filter'; | ||
}; | ||
|
||
return { | ||
init: function() { | ||
setUpEventListeners(); | ||
} | ||
}; | ||
})(UIController, storageController); | ||
|
||
controller.init(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why UI controller should know how to filter data? As I can see in your to do list
UIController
- it's classic view component. All what should do this controller - correctly display data to user. Filtering of the data should docontroller
(line 145) component and just put array of filtered tasks to UI controller