Firebase 배우기 22 – 파이어베이스에서 게시판 만들기 (3) – 삭제 (Delete)와 수정 (Edit) 기능 추가하기

Firebase 배우기 22 – 파이어베이스에서 게시판 만들기 (3) – 삭제 (Delete)와  수정 (Edit) 기능 추가하기

파이어 베이스로 게시판 만들기 기초

이전 글(https://blog.naver.com/mythee1/223499829728)에서 파이어 베이스를 이용하여 간단한 게시판을 만드는 방법을 소개했었고,

이렇게 만든 게시판에 페이지 분할에 대해서도 별도의 추가글(https://blog.naver.com/mythee1/223510496924)에서 소개한 바 있었다.

다만 이렇게 소개한 것은 가장 기본적인 게시판의 형태와, 글의 작성 및 표시 기능 정도였었다.

편집, 삭제 기능 추가하기

그런데, 게시판의 글들은 상황에 따라 수정을 하거나, 또는 삭제도 가능해야만 하기 때문에, 기존에 파이어 베이스로 만든 게시판도 정상적으로 운영하려면 당연하게 도 삭제와 수정 기능이 필요하다.

이를 위해 다음 화면에서처럼, 특정 글의 번호를 지정하고, 삭제ㅔ 또는 수정 버튼을 눌러주는 방식을 해당 기능을 구현하기로 했다.

게시물에 비밀번호 기능 추가하기

또한 글을 실제로 작성한 사람이 아닌 타인에 의한 무분별한 삭제 또는 수정을 방지하기 위해, 글 작성 시에 해당 글에 비밀번호를 설정하도록 하는 기능을 추가했다. 이러한 비밀번호는 각각의 게시물마다 글을 쓰는 사람이 임의로 지정할 수 있으며, DB에 각각의 게시물 내용과 함께 저장되도록 구성했다.

게시판의 글을 수정하거나 삭제할 때는 다음과 같은 부분에 글 작성 시에 입력했던 비밀번호를 넣어주도록 함으로써, 작성자만이 해당 글을 수정하거나 삭제할 수 있도록 했다.

편집, 삭제 동작 선택을 위한 버튼 추가하기

이러한 동작을 입력받는 HTML 부분은 기존 HTML에 다음 부분을 추가하여 게시물 번호와, 해당 게시글의 비밀번호를 입력받고, 수정 및 삭제에 대한 버튼 동작을 입력받도록 했다.

삭제 기능 구현하기

먼저 삭제 기능은 다음과 같이 버튼 핸들러 방식으로 구현했는데, 이름은 “삭제”이지만 실제로는 해당 레코드를 삭제하는 대신 내용을 모두 공란으로 또는 “삭제 표시”로 대체해서 update 하는 방식을 선택했다. 당초 생성일이었던 날짜 정보는 이렇게 삭제된 경우에는 삭제 일로 변경하여 표시하도록 함께 Update가 되도록 했다.

또한 실수로 인한 불필요한 삭제를 피하기 위해, 화면상에서 사용자의 의도를 확인하는 단계를 if(confirm()) 구문을 이용하여 구현하였고,

그 이후, 게시물의 비밀번호와 삭제 요청 시 입력한 비밀번호의 일치 여부를 확인하는 단계를 추가하여 구성하였다.

수정 기능 구현하기

수정 기능 역시 버튼 핸들러 방식으로 구현했는데, 수정 작업 전 게시물의 비밀번호와 수정요청 시 입력한 비밀번호의 일치 여부를 확인하는 단계를 포함하여 핸들러의 골격을 구성하였다. 참고로, 삭제 기능에서 포함시켰던 if(confirm()) 구문은 수정 기능에서는 굳이 필요하지 않을듯하여 포함시키지 않았다.

실제 ㅅ후정 작업은 편집을 위한 기존 필드값의 표시 등이 필요했기에, 이 핸들러 내에 포함시키기보다는 별도의 새로운 페이지에서 작업하도록 페이지를 전환하는 방식을 사용했는데, 이때 DB 문서의 id 정보를 전달해야 하기 때문에, 위의 핸들러에서 다음과 같이 URL 정보에 id 값을 파라미터로 추가하여 전달하는 방식을 사용했다.

이렇게 전환된 페이지에서는 다음 구문을 이용하여 해당 id를 추출하고,

다음 form으로

추출된 id에 해당되는 기존 데이터 값을 불러와

화면에 다음과 같이 표시한 다음

게시 버튼 선택 시 새로운 값으로 입력받아

다음 명령을 통해 값을 업데이트하는 방식을 사용했다.

이때, 게시물의 날짜 표시는 수정된 날짜로 변경되도록 함께 수정했으며, 게시물의 고유번호는 수정 없이 원래의 상태를 유지하도록 했다.

수정이 완료되면 게시판 화면으로 되돌아가도록 구성했다.

참고로, 수정 작업이 실제 이루어지는 페이지의 전체 소스는 다음과 같다.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>게시판 새글 쓰기</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
      input, textarea {
border: 1px solid black !important; /* 외곽선의 너비를 2px로 설정합니다 */
}
</style>
<script src="https://www.gstatic.com/firebasejs/8.6.5/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.5/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.5/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.6.5/firebase-storage.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<script src="/firebaseConfig.js"></script>
</head>
<body>
<div class="container mt-5">
<form id="post-form">
<h4> 글 수정하기 ...</h4>
<input type="text" class="form-control  mt-4 mb-5" id="title" placeholder="제목">
<textarea class="form-control mt-4 mb-5" id="content"  rows="8" cols="50">내용</textarea>
<input type="text" class="form-control  mt-4 mb-5" id="author" placeholder="글쓴이">
<input type="editpwd" class="form-control  mt-4 mb-5" id="editpwd" placeholder="수정 비밀번호">
<button type="submit" class="btn btn-danger mt-2 mb-5">게시</button>
</form>
</div>
<script>
var db = firebase.firestore();
var params = new URLSearchParams(window.location.search);
    id = params.get('id'); 

    document.getElementById('post-form').addEventListener('submit', function(e) {
        e.preventDefault();
var title = document.getElementById('title').value;
var content = document.getElementById('content').value;
var author = document.getElementById('author').value;
var editpwd = document.getElementById('editpwd').value;
        
        db.collection("posts").doc(id).update({
title: title,
content: content,
author: author,
editpwd: editpwd,
createdAt: firebase.firestore.FieldValue.serverTimestamp()
})
.then((docRef) => {
                console.log("Document successfully updated!");
setTimeout(() => window.location.href = "/boardread.html", 100)
})
.catch((error) => {
                console.error("Error updating document: ", error);
});
});

        window.onload = function() {
var docRef = db.collection("posts").doc(id);

            docRef.get().then((doc) => {
if (doc.exists) {
var data = doc.data();
                    document.getElementById('title').value = data.title;
                    document.getElementById('content').value = data.content;
                    document.getElementById('author').value = data.author;
                    document.getElementById('editpwd').value = data.editpwd;
} else {
                    console.log("No such document!");
}
}).catch((error) => {
                console.log("Error getting document:", error);
});
};
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>