I converted the form data into ToDo items!
Basically at the start of the app, I create a TODO list that keeps track of all of my TODOS internally.
The submission of the form first creates a TODO item, and then appends it to the list via a setter method.
I used the following code to add a TODO:
const myForm = document.querySelector("#toDoForm") as HTMLFormElement; // HTMLFormElement
myForm?.addEventListener("submit", (event) => {
event.preventDefault();
const myFormData = new FormData(myForm) as unknown as Iterable<
[IToDoItem, FormDataEntryValue]
>;
const myFormDataObject: IToDoItem = Object.fromEntries(myFormData);
const objectToAdd: IToDoItemCls = {
toDoName: myFormDataObject.toDoName,
toDoDescription: myFormDataObject.toDoDescription,
id: Date.now().toString(36) + Math.random().toString(36).substring(2),
};
myToDoList.addToDoItem(objectToAdd);
myForm.reset();
});
Well actually each TODO item manages it's own render!
Basically, when a todo is created, it has a method stored on it called render()
.
When a todo is created, the todo list loops through all the todos and runs that method on each of them.
That method generates the HTML of the todo and appends it to the parent!
As far as the local storage?
Well whenever one is either created, updated, or deleted, I pass a reference to the parent todo list to the TODO items, and those use that method to update the local storage item 'todos' with the JSON stringify of the elements that are needed to construct the todos on load. You cannot send some things like the reference to the parent.
Here's the code for that:
class ToDoItem {
id:string;
name:string;
description:string;
parentEl:HTMLElement;
parentClassRef:ToDoList;
constructor(id:string, name:string, description:string, parentEl:HTMLElement, parentRef:ToDoList){
this.id = id;
this.name = name;
this.description = description;
this.parentEl = parentEl;
this.parentClassRef = parentRef;
}
render(){
const {newHtml, ref} = this.generateHTML();
if(ref){
this.parentEl.replaceChild(newHtml, ref);
return this.addEventListeners();
}
this.parentEl.appendChild(newHtml)
this.addEventListeners();
}
update(name:string, description:string){
this.name = name;
this.description = description;
this.render();
this.parentClassRef.updateLocalStorage();
}
generateHTML(){
const ref = document.querySelector(`#${this.id}`);
const newDiv = document.createElement('div');
newDiv.classList.add('card', 'p-4', 'mt-3');
newDiv.id = this.id;
const innerHtmlString = `
${this.name}
${this.description}
`
newDiv.innerHTML = innerHtmlString;
return{
newHtml:newDiv,
ref:ref,
}
}
addEventListeners(){
const deleteButton = document.querySelector(`#delete-${this.id}`);
console.log(deleteButton)
const updateForm = document.querySelector(`#update-${this.id}`);
deleteButton?.addEventListener('click', ()=>{
myToDoList.removeToDoItem(this.id);
});
updateForm?.addEventListener('submit', (e)=>{
e.preventDefault();
const myForm = e.target as HTMLFormElement;
const { name, description } = Object.fromEntries(
new FormData(myForm) as unknown as Iterable<
[{ name: string; descrption: string }, FormDataEntryValue]
>
); ;
this.update(name, description);
})
}
}
class ToDoList {
toDoList: ToDoItem[];
container: HTMLElement;
constructor(container: HTMLElement, defaultValues:IToDoItem[] = []) {
this.container = container;
this.toDoList = defaultValues.map((todo) => {
return new ToDoItem(
todo.id,
todo.toDoName,
todo.toDoDescription,
myTableContainer,
this
);
});
}
addToDoItem(toDoItem: IToDoItemCls) {
const newTodo = new ToDoItem(
toDoItem.id,
toDoItem.toDoName,
toDoItem.toDoDescription,
this.container,
this
);
this.toDoList.push(newTodo);
this.updateLocalStorage();
this.render();
}
removeToDoItem(id: string) {
const removeThis = document.querySelector(`#${id}`);
removeThis?.remove();
const newTodos = this.toDoList.filter((todo) => todo.id != id);
this.toDoList = newTodos;
this.updateLocalStorage();
}
updateLocalStorage(){
console.log(this.toDoList);
const jsonString = this.toDoList.map(({ id, name, description }) => {
return { id, toDoName:name, toDoDescription:description };
});
localStorage.setItem("todos", JSON.stringify(jsonString));
}
render() {
this.toDoList.forEach((todo) => {
todo.render();
});
}
}
I had no idea how to test this code.
console.log('help?');