Skip to content

Instantly share code, notes, and snippets.

@youliangdao
Created December 3, 2022 00:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save youliangdao/3ec60ef2015d86e769c1dffcc93126bd to your computer and use it in GitHub Desktop.
Save youliangdao/3ec60ef2015d86e769c1dffcc93126bd to your computer and use it in GitHub Desktop.
class View {
/**
* TODOの配列からUIを生成する関数
* @param {Todo[]} todos
*/
render(todos) {
const todosEl = document.getElementById("todos");
todosEl.innerHTML = "";
const fragment = document.createDocumentFragment();
todos.forEach((todo) => {
const todoEl = this._createTodoElement(todo);
fragment.appendChild(todoEl);
});
todosEl.appendChild(fragment);
}
/**
* TODO要素を作る
* @param {id: number, task: string} todo
* @returns todoのHTML要素
*/
_createTodoElement(todo) {
const { id, title, checked } = todo;
const todoEl = document.createElement("li");
todoEl.id = `todo-${id}`;
const checkBoxEl = document.createElement("input");
todoEl.appendChild(checkBoxEl);
const labelEl = document.createElement("label");
labelEl.innerText = title;
checkBoxEl.type = "checkbox";
checkBoxEl.id = `checkbox-${todo.id}`;
checkBoxEl.checked = checked;
todoEl.appendChild(labelEl);
if (checked) {
todoEl.className = `checked`;
} else {
todoEl.className = "";
}
const buttonEl = document.createElement("button");
buttonEl.id = `button-${id}`;
buttonEl.innerText = "削除";
todoEl.appendChild(buttonEl);
return todoEl;
}
}
const view = new View();
class Controller {
setup() {
this.handleSubmitForm();
}
flash(todos) {
view.render(todos);
// イベントハンドラの付け直し
todos.forEach((todo) => {
const id = todo.id;
this.handleCheckTask(id);
this.handleClickDeleteTask(id);
});
}
/**
* タスク送信時にTODO追加とUI反映をする
*/
handleSubmitForm() {
window.addEventListener("load", () => {
const formEl = document.getElementById("task-send-form");
formEl.addEventListener("ajax:success", (ev) => {
this.flash(ev.detail[0]);
});
});
}
/**
* 指定したcheckboxの状態変化に応じてTODO更新とUI反映をする
* @param {number} id TODOのid
*/
handleCheckTask(id) {
const checkBoxEl = document.getElementById(`checkbox-${id}`);
checkBoxEl.addEventListener("change", (e) => {
const params = {
task: {
checked: e.target.checked,
},
};
fetch(`http://localhost:3000/tasks/${id}`, {
method: "PATCH",
headers: {
"X-CSRF-Token": Rails.csrfToken(),
"content-type": "application/json",
},
body: JSON.stringify(params),
})
.then((res) => {
return res.json();
})
.then((json) => {
this.flash(json);
});
});
}
/**
* 指定したTODO削除とUI反映をする
* @param {*} id TODOのid
*/
handleClickDeleteTask(id) {
const buttonEl = document.getElementById(`button-${id}`);
buttonEl.addEventListener("click", () => {
fetch(`http://localhost:3000/tasks/${id}`, {
method: "DELETE",
headers: {
"X-CSRF-Token": Rails.csrfToken(),
"content-type": "application/json",
},
})
.then((res) => {
return res.json();
})
.then((json) => {
this.flash(json);
});
});
}
}
const formController = new Controller();
formController.setup();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment