본문 바로가기
Javascript

Javascript CRUD를 활용한 댓글게시판을 만들기 2탄

by 개발적금 2022. 11. 18.

안녕하세요. 개발적금입니다.

오늘은 CRUD를이용해 댓글게시판 만들기 2탄입니다.

저번에 포스팅했을때는 Create 부분과 Read부분까지 했습니다.

오늘은 값을 Update(수정)하고 Delete(삭제)하는것을 구현해보겠습니다.


 

목차

 

1. Update(수정하기) / Delete(삭제하기)

 


 

 

1. Update(수정하기)

 

const commentFrm = document.querySelector("#commentFrm")
const commentList = document.querySelector("#comment-list")
const state = []

class Comment {
    constructor(content) {
        this.userid = "web7722"
        this.Content = content
        // this.date = "2022-11-16"
        this.updated = false
        this.updateValue = ""
        this.now = new Date()
    }

    set Content(value) {
        if (value.length === 0) throw new Error("Content가 비워있음.")
        this.content = value
    }

    getToday(separator = "") {
        const date = this.now
        let mm = date.getMonth() + 1 // 0 ~ 11
        let dd = date.getDate()
        let yyyy = date.getFullYear()
        mm = (mm > 9 ? "" : "0") + mm
        dd = (dd > 9 ? "" : "0") + dd // 1 -> 01
        const arr = [yyyy, mm, dd]
        return arr.join(separator)
    }
}

function addComment(instance) {
    state.push(instance)
}

function createRow(index) {
    const ul = document.createElement("ul")
    const li1 = document.createElement("li")
    const li2 = document.createElement("li")
    const li3 = document.createElement("li")

    const deleteBtn = document.createElement("span")

    ul.append(li1)
    ul.append(li2)
    ul.append(li3)

    ul.setAttribute("class", "comment-row")
    ul.setAttribute("data-index", index)
    li1.setAttribute("class", "comment-id")
    li2.setAttribute("class", "comment-content")
    li3.setAttribute("class", "comment-date")
    deleteBtn.setAttribute("class", "comment-delete-btn")
    deleteBtn.innerHTML = "❌"

    li1.innerHTML = state[index].userid
    if (state[index].updated) {
        const input = document.createElement("input")

        input.addEventListener("keyup", function (e) {
            if (e.keyCode === 13) {
                state[index].content = e.target.value
                state[index].updated = false
                drawing()
            } else {
                state[index].updateValue = e.target.value
            }
        })
        
        input.setAttribute("class", "comment-update-input")
        input.value = state[index].updateValue
        li2.append(input)
    } else {
        li2.innerHTML = state[index].content
        li2.append(deleteBtn)
    }

    li3.innerHTML = state[index].getToday("/")

    return ul
}

function drawing() {
    commentList.innerHTML = ""
    for (let i = state.length - 1; i >= 0; i--) {
        const row = createRow(i)
        commentList.append(row)
    }
}

function submitHandler(e) {
    e.preventDefault()
    const form = e.target
    const value = form.content.value

    try {
        const instance = new Comment(value)
        addComment(instance)
        drawing()
    } catch (error) {
        alert(error.message)
        console.log(error)
    }
    form.content.focus()
    e.target.reset()
}

function clickHandler(e) {
    if (e.target.className === "comment-content") {
        const index = parseInt(e.target.parentNode.dataset.index)
        state[index].updated = true
        state[index].updateValue = state[index].content
        drawing()
    } else if (e.target.className === "comment-delete-btn") {
        const index = e.target.parentNode.parentNode.dataset.index
        state.splice(index, 1)
        drawing()
    }

    if (e.target.className !== "comment-content") return
}

commentList.addEventListener("click", clickHandler)
commentFrm.addEventListener("submit", submitHandler)

 

저번에 구현했었던 코드에 더 추가하여 가져왔습니다. 제일먼저 보셔야할것이

Class 생성자 함수에 추가된 항목들입니다.

 

update -> 기본값은 false이고 click이 발동되면 true로 바뀌고 수정이 완료되면 다시 false로 바뀝니다

updateValue -> 수정된 값들을 저장하는곳입니다.

 

 

2.1 "Click" Event발생입니다.

 

-> click Event가 발생하여 clickHandler부분에서 조건문을 통해 ClassName을 확인하여,

-> 내용을 클릭하였으면(ClassName = "comment-content")

->  const index = parseInt(e.target.parentNode.dataset.index)를 사용하여

-> e.target의 부모값의 index를 가져와 Number형으로 바꿔준 뒤 , 변수에 저장하였습니다.

-> 이과정은 click된 content의 index를 알아보기 위함입니다.

-> update와 updateValue 값을 저장한 뒤 다시 drawing()로 화면출력을 해줍니다.

 

li1.innerHTML = state[index].userid
    if (state[index].updated) {
        const input = document.createElement("input")

        input.addEventListener("keyup", function (e) {
            if (e.keyCode === 13) {
                state[index].content = e.target.value
                state[index].updated = false
                drawing()
            } else {
                state[index].updateValue = e.target.value
            }
        })
        
        input.setAttribute("class", "comment-update-input")
        input.value = state[index].updateValue
        li2.append(input)
    } else {
        li2.innerHTML = state[index].content
        li2.append(deleteBtn)
    }

    li3.innerHTML = state[index].getToday("/")

 

-> drawing() => createRow()에서  추가된 부분입니다.  보셔야 할 부분이

-> " li2 " 조건문 부분에서 , state[index].updated 의 true / false 에 따라서

-> input box를 생성하여 "keyup" Event를 발생시키고 , "e.keyCode === 13" -> 키보드 입력값이 엔터일경우,

-> 값들을 저장하고 updated의 상태를 false로 바꿔놓습니다.

-> 그리고 난 후에 수정된 input box에 class설정을 해주시고 다시 li2.append합니다

 

2.2 Delete

 

function clickHandler(e) {
    if (e.target.className === "comment-content") {
        const index = parseInt(e.target.parentNode.dataset.index)
        state[index].updated = true
        state[index].updateValue = state[index].content
        drawing()
    } else if (e.target.className === "comment-delete-btn") {
        const index = e.target.parentNode.parentNode.dataset.index
        state.splice(index, 1)
        drawing()
    }

    if (e.target.className !== "comment-content") return
}

 

-> ClickHandler에서 click된 (className === "comment-delete-btn") 일경우 , 

-> update와 똑같이 , 부모값의 인덱스를 찾아서 , splice()를 통해 값을 제거해준후에

-> drawing()으로 다시 다른값들을 출력합니다.

 

 


 

update와 delete부분을 리뷰해보았습니다.

조금더 많이 연습해야지 손이자동으로 움직일것 같습니다..

감사합니다