Skip to content
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

ФТ-201, Лапшин Евгений, Сыч Эрнест, Джевелло Алексей #19

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions index.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ button {
.todo-list li label {
flex-grow: 1;
}

.aaaa {
color: #0ff;
}
155 changes: 135 additions & 20 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function createElement(tag, attributes, children) {
function createElement(tag, attributes, children, callbacks=[]) {
const element = document.createElement(tag);

if (attributes) {
Expand All @@ -21,20 +21,93 @@
element.appendChild(children);
}

for (let pair of callbacks) {
element.addEventListener(pair.eventName, pair.callback);
}

return element;
}

class Component {
constructor() {
}

update() {
const parent = this._domNode.parentElement;
parent.removeChild(this._domNode);
parent.appendChild(this.getDomNode());
}

getDomNode() {
this._domNode = this.render();
return this._domNode;
}
}

class TodoList extends Component {
constructor(TodoListId=0){
super();
this.addTask = new AddTask(this.createOnAddTask());
this.localStorageFieldName = `TodoList_${TodoListId}_state`;
try{
const saved_state = JSON.parse(localStorage.getItem(this.localStorageFieldName));
console.log(saved_state);
if (saved_state !== null){
this.state = saved_state;
return;
}
} catch {

}

this.state = {
tasks: [
{ title: "Сделать домашку", progress: false, isDeleteClicked: false },
{ title: "Сделать практику", progress: false, isDeleteClicked: false },
{ title: "Пойти домой", progress: false, isDeleteClicked: false }
],
newTaskName: ""
};
this.saveState();
}

saveState() {
const stateString = JSON.stringify(this.state)
localStorage.setItem(this.localStorageFieldName, stateString);
}

createOnAddTask() {
return (function() {
this.state.tasks.push({ title: this.state.newTaskName, progress: false, isDeleteClicked: false });
this.saveState();
this.update();
}).bind(this);
}

createOnAddInputChange() {
return (function(event) {
this.state.newTaskName = event.target.value;
this.saveState();
}).bind(this);
}

createOnDeleteTask(task){
return (function(event) {
if (!task.isDeleteClicked){
task.isDeleteClicked = true;
event.target.setAttribute('style', 'background:red;')
}
else{
var index = this.state.tasks.indexOf(task);
if (index !== -1) {
this.state.tasks.splice(index, 1);
}
}
this.saveState();
this.update();
}).bind(this);
}

render() {
return createElement("div", { class: "todo-list" }, [
createElement("h1", {}, "TODO List"),
Expand All @@ -43,30 +116,72 @@ class TodoList extends Component {
id: "new-todo",
type: "text",
placeholder: "Задание",
}),
createElement("button", { id: "add-btn" }, "+"),
]),
createElement("ul", { id: "todos" }, [
createElement("li", {}, [
createElement("input", { type: "checkbox" }),
createElement("label", {}, "Сделать домашку"),
createElement("button", {}, "🗑️")
]),
createElement("li", {}, [
createElement("input", { type: "checkbox" }),
createElement("label", {}, "Сделать практику"),
createElement("button", {}, "🗑️")
]),
createElement("li", {}, [
createElement("input", { type: "checkbox" }),
createElement("label", {}, "Пойти домой"),
createElement("button", {}, "🗑️")
]),
value: this.state.newTaskName
},
{},
[
{ eventName: "change", callback: this.createOnAddInputChange() }
]
),
createElement("button", { id: "add-btn" }, "+",
[
{ eventName: "click", callback: this.addTask.OnAddTask }
]
),
]),
createElement("ul", { id: "todos" }, this.state.tasks.map(
v => (new Task(this.createOnDeleteTask.bind(this), this.saveState.bind(this), v)).render())
),
]);
}
}

class AddTask extends Component {
constructor(OnAddTask) {
super();
this.OnAddTask = OnAddTask;
}
}

class Task extends Component {
constructor(OnDelete, OnChange, state) {
super();
this.state = state;
this.OnDelete = OnDelete(this.state);
this.OnChange = OnChange;
}

render() {
const input = createElement("input",
this.state.progress ? { type: "checkbox", checked: "checked" } : { type: "checkbox" },
{},
[{eventName: "change", callback: this.createOnTaskChecked()}]
);

const label = createElement("label", {}, this.state.title);
if (this.state.progress)
label.setAttribute('style', 'color:#aaa;');

const button = createElement("button", {}, "🗑️", [{eventName: "click", callback: this.OnDelete}]);
if (this.state.isDeleteClicked)
button.setAttribute('style', 'background:red;');

return createElement("li", {}, [
input,
label,
button
])
}

createOnTaskChecked(){
return (function(event){
this.state.progress = !this.state.progress;
event.target.nextElementSibling.setAttribute('style', this.state.progress ? 'color:#aaa;' : '');
this.OnChange();
}).bind(this);
}
}

document.addEventListener("DOMContentLoaded", () => {
document.body.appendChild(new TodoList().getDomNode());
});