기록하는 개발자

[vanillaJs] mongoDB, node.js, fetch api로 crud page 만들기-2. frontend 본문

Web/Javascript

[vanillaJs] mongoDB, node.js, fetch api로 crud page 만들기-2. frontend

밍맹030 2022. 11. 12. 15:48
728x90

이 글은 아래 포스트와 이어집니다 : )

https://mingmeng030.tistory.com/255

 

[vanillaJs] mongoDB, node.js, fetch api로 crud page 만들기-1. backend 구성

mongoDB와 node.js, 그리고 javascript의 fetch api를 사용하여 crud가 가능한 페이지를 만들어 보았다. react가 역시 편하다는 것을 또 깨닫는 과정이었다.. mongoDB를 사용하고 nodejs로 restful API를 만들어 본 것

mingmeng030.tistory.com

 

완성 화면

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRUD with Fetch API</title>
    <link rel="stylesheet" type="text/css" href="./postForm.css" />    
    <link rel="stylesheet" type="text/css" href="./card.css" />    
</head>
<body>
    <div class="top-container">
        <div class="row">
            <div class="column">
                <h2 class="header">Add new Post</h2>
                <form class="add-post-form">
                    <div class="form-group">
                        <label for="title">Title</label>
                        <input type="text" class="form-control" id="title-value"></input>                    
                    </div>
                    <div class="form-group">
                        <label for="body">Content</label>
                        <textarea type="text" class="form-control" id="body-value"></textarea>                    
                    </div>
                    <button type="submit" class="btn-submit">Add Post</button>
                </form>
            </div>
        </div>
        <div class="posts-list">
        </div>
    </div>
    <script src="./main.js"></script>
</body>
</html>

main.js

const postsList = document.querySelector(".posts-list");
const addPostForm = document.querySelector(".add-post-form");
const titleValue = document.getElementById("title-value");
const bodyValue = document.getElementById("body-value");
const btnSubmit = document.querySelector(".btn-submit");

let output = "";
const url = `http://localhost:5000/api/posts`;

const renderPosts = (posts) => {
  posts.map((post) => {
    output += `
    <div class="card-container">
      <div class="card" data-id=${post._id}>                
          <p class="card-title">${post.title}</p>
          <p class="card-date">${post.date}</p>
          <p class="card-content">${post.body}</p>
          <a href="#" class="card-edit-link" id="edit-post">edit</a>
          <a href="#" class="card-delete-link" id="delete-post">delete</a>
      </div>
  </div>`;
  });
  postsList.innerHTML = output;
};

//Get
fetch(url)
  .then((res) => res.json())
  .then((data) => renderPosts(data));


//delete, update
postsList.addEventListener("click", (e) => {
  e.preventDefault();
  let delButtonIsPressed = e.target.id == "delete-post";
  let editButtonIsPressed = e.target.id == "edit-post";

  let id = e.target.parentElement.dataset.id;
  
  // delete
  if (delButtonIsPressed) {
    fetch(`${url}/${id}`, {
      method: "DELETE",
    })
      .then((res) => res.json())
      .then(() => location.reload());
  }
  
  // update
  if (editButtonIsPressed) {
    btnSubmit.innerHTML = "Edit Post";
    const parent = e.target.parentElement;
    let titleContent = parent.querySelector(".card-title").textContent;
    let bodyContent = parent.querySelector(".card-content").textContent;

    titleValue.value = titleContent;
    bodyValue.value = bodyContent;
  }
  
  // 내용 수정 후 'Edit Post' 버튼 클릭한 경우
  btnSubmit.addEventListener("click", (e) => {
    e.preventDefault();
    btnSubmit.innerHTML = "Add Post";

    fetch(`${url}/${id}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        title: titleValue.value,
        body: bodyValue.value,
      }),
    })
      .then((res) => res.json())
      .then(() => location.reload());
  });
});

//Create
addPostForm.addEventListener("submit", (e) => {
  e.preventDefault();
  fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: titleValue.value,
      body: bodyValue.value,
    }),
  })
    .then((res) => res.json())
    .then((data) => {
      const dataArr = [];
      dataArr.push(data);
      renderPosts(dataArr);
    })
    .catch((err) => console.log(err));
  titleValue.value = "";
  bodyValue.value = "";
});

생성

- 기존 버튼 'Add Post'

수정

-  'Edit Post' 로 변경

postForm.css

.top-container {
  width: 40%;
  display: flex;
}

.column {
  margin: 50px 30px 30px 70px;
}

.form-group {
  margin-top: 20px;
  margin-bottom: 10px;
}

label {
  margin-bottom: 10px;
  font-size: 16px;
  display: block;
}

input,
textarea {
  padding: 10px;
  border-radius: 10px;
  border: 1px solid rgb(180, 180, 180);
  width: 450px;
}

input {
  font-size: 17px;
  height: 25px;
  font-weight: bold;
}

textarea {
  font-size: 15px;
  height: 120px;
  resize: none;
}

.btn-submit {
  padding: 10px;
  border-radius: 10px;
  border: 1px solid rgb(180, 180, 180);
}

card.css

.posts-list {
  position: relative;
  margin: 50px 30px 0 70px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

.card {
  background-color: rgb(230, 235, 229);
  width: 180px;
  height: 200px;
  padding: 10px 30px 10px 30px;
  margin: 0 30px 30px 0;
  border-radius: 10px;
}

.card-title {
  color: rgb(43, 66, 16);
  font-size: 16px;
  font-weight: bold;
  height: 20px;
}

.card-date {
  color: rgba(79, 112, 43, 0.866);
  font-size: 12px;
}
.card-content {
  color: rgba(41, 69, 14, 0.866);
  height: 70px;
  font-size: 13px;
}

.card-edit-link,
.card-delete-link {
  color: rgb(25, 38, 0);
  text-decoration: none;
  margin-right: 20px;
  font-size: 13px;
}

 

참고
https://www.youtube.com/watch?v=ccX3ApO4qz8&list=PLUO4kcgmSFDivLwVxFZtdLct_vIDVFnwQ&index=6&t=1196s
728x90