diff --git a/js/app.js b/js/app.js index 1f71234..5b182cc 100644 --- a/js/app.js +++ b/js/app.js @@ -36,9 +36,27 @@ const App = { ` ); }, + removeTodo(id) { + App.$.list.querySelector(`[data-id="${id}"]`).remove(); + }, + toggleTodo(todo) { + const el = App.$.list.querySelector(`[data-id="${todo.id}"]`); + if (todo.completed) { + el.classList.add('completed'); + el.querySelector('input').setAttribute('checked', true); + } else { + el.classList.remove('completed'); + el.querySelector('input').removeAttribute('checked'); + } + }, }, init() { Todos.addEventListener('save', App.render); + Todos.addEventListener('add', (e) => App.renderAdd(e.detail)); + Todos.addEventListener('remove', (e) => App.renderRemove(e.detail)); + Todos.addEventListener('toggle', (e) => App.renderToggle(e.detail)); + Todos.addEventListener('update', (e) => App.renderUpdate(e.detail)); + Todos.addEventListener('clear', (e) => App.renderClear(e.detail)); App.filter = getURLHash(); window.addEventListener('hashchange', () => { App.filter = getURLHash(); @@ -107,19 +125,40 @@ const App = { li.querySelector('[data-todo="edit"]').value = todo.title; return li; }, - render() { + _renderUI() { const count = Todos.all().length; App.$.setActiveFilter(App.filter); - replaceWith( - App.$.list, - Todos.all(App.filter).map((todo) => App.createTodoItem(todo)) - ); App.$.showMain(count); App.$.showFooter(count); App.$.showClear(Todos.hasCompleted()); App.$.toggleAll.checked = Todos.isAllCompleted(); App.$.displayCount(Todos.all('active').length); }, + render() { + replaceWith( + App.$.list, + Todos.all(App.filter).map((todo) => App.createTodoItem(todo)) + ); + App._renderUI(); + }, + renderAdd(todo) { + App.$.list.append(App.createTodoItem(todo)); + App._renderUI(); + }, + renderRemove(todoId) { + App.$.removeTodo(todoId); + App._renderUI(); + }, + renderToggle(todo) { + App.$.toggleTodo(todo); + App._renderUI(); + }, + renderClear(todos) { + todos.forEach((todo) => { + App.$.removeTodo(todo.id); + }); + App._renderUI(); + }, }; App.init(); diff --git a/js/store.js b/js/store.js index 42fb09a..07115cf 100644 --- a/js/store.js +++ b/js/store.js @@ -5,7 +5,7 @@ export const TodoStore = class extends EventTarget { this._readStorage(); // handle todos edited in another window window.addEventListener( - "storage", + 'storage', () => { this._readStorage(); this._save(); @@ -17,50 +17,53 @@ export const TodoStore = class extends EventTarget { this.isAllCompleted = () => this.todos.every((todo) => todo.completed); this.hasCompleted = () => this.todos.some((todo) => todo.completed); this.all = (filter) => - filter === "active" + filter === 'active' ? this.todos.filter((todo) => !todo.completed) - : filter === "completed" + : filter === 'completed' ? this.todos.filter((todo) => todo.completed) : this.todos; } _readStorage() { - this.todos = JSON.parse( - window.localStorage.getItem(this.localStorageKey) || "[]" - ); + this.todos = JSON.parse(window.localStorage.getItem(this.localStorageKey) || '[]'); } - _save() { - window.localStorage.setItem( - this.localStorageKey, - JSON.stringify(this.todos) - ); - this.dispatchEvent(new CustomEvent("save")); + _save(event, data) { + console.log('firing', event, data); + window.localStorage.setItem(this.localStorageKey, JSON.stringify(this.todos)); + console.log(event ? event : 'save', data ? { detail: data } : ''); + this.dispatchEvent(new CustomEvent(event ? event : 'save', data ? { detail: data } : null)); } // MUTATE methods add(todo) { - this.todos.push({ + let newTodo = { title: todo.title, completed: false, - id: "id_" + Date.now(), - }); - this._save(); + id: 'id_' + Date.now(), + }; + this.todos.push(newTodo); + this._save('add', newTodo); } remove({ id }) { this.todos = this.todos.filter((todo) => todo.id !== id); - this._save(); + this._save('remove', id); } toggle({ id }) { - this.todos = this.todos.map((todo) => - todo.id === id ? { ...todo, completed: !todo.completed } : todo + this.todos = this.todos.map((todo) => (todo.id === id ? { ...todo, completed: !todo.completed } : todo)); + this._save( + 'toggle', + this.todos.find((todo) => id === todo.id) ); - this._save(); } clearCompleted() { + let cleared = this.todos.filter((todo) => todo.completed); this.todos = this.todos.filter((todo) => !todo.completed); - this._save(); + this._save('clear', cleared); } update(todo) { this.todos = this.todos.map((t) => (t.id === todo.id ? todo : t)); - this._save(); + this._save( + 'update', + this.todos.find((todo) => id === todo.id) + ); } toggleAll() { const completed = !this.hasCompleted() || !this.isAllCompleted();