HYEWON JUNG의 개발일지
20231010 Til /방명록 삭제하기 & input 필수 입력값주기 본문
페이지가 거의 다 완성 되었다. 5명의 조원 중에 2명밖에 남지 않았지만 열심히 머리 모아서 만들었다. 페이지를 만들면서 대부분은 웹개발 강의에서 나왔던 부분을 고쳐서 사용했고 그 외에 스크립트 부분은 새롭게 배우면서 작성했다.
내가 한 양식은 폼에 입력값을 넣고 버튼을 누르면 DB에 문서 추가 되게 하기.
우선 firebase세팅을 해주고 (지금 생각안남,, 강의 보고 다시 상기시키려했지만 강의가 잘못들어와있어서,,)```
<script type = "module">
로 바꿔주고 본격적으로 버튼이 click 되었을 때 입력값이 문서에 들어가도록 해보겠다. 방명록으로 이름, 비밀번호, 내용 이렇게 넣을 것이다.
<script type = "module">
$("selector").click(async function () {
let name = $('#name').val();
let comment = $('#comment').val();
let doc = {
'name': name, (반점 없으면 실행 안됨..)
'comment':comment
};
await addDoc(collection(db, "데이터베이스의 컬렉션 이름"), doc);
---문서 추가 후 새로고침---
alert('반가워요!')
window.location.reload();
})
</script>
$(' ').val(); 은 ' '안의 값의 value를 뜻하는데 지근은 아래의 input 태그에서 id로 설정된 것들을 정의했다.
window.location.reload();는 자동으로 새로고침
이렇게 addDoc을 해준 뒤 특정 양식으로 다시 getDoc을
let docs = await getDocs(collection(db, "데이터베이스 컬렉션 이름"));
docs.forEach((doc) => {
let row = doc.data();
let name = row['name'];
let comment = row['comment'];
let temp_html = `
<div class="col">
<div class="card h-100">
<div class="postData card-body" data-id="${doc.id}">
<h5 class="card-title">${name}</h5>
<p class="card-text">${comment}</p>
</div>
</div>
</div>`;
$('#card').append(temp_html);
});
이렇게 Doc에서 값을 가져와서 카드로 나타나게 만들었다.
여기까진 쉬운 문제 였지만 방명록을 삭제할 수 있게 하자란 팀원분의 말에 우리는 다시 연구에 들어갔다.
삭제를 위해 우리가 필요한 것은
- 작성폼에 비밀번호 입력란 추가하기
- 카드에 삭제버튼 추가하기
- 비밀번호 입력할 곳 만들기
- 입력된 비밀번호 DB에 추가하기
- DB의 값과 새로 입력된 비밀번호가 같은지 확인하는 조건문 쓰기
정도를 생각했다.
우선 난 틀부터 만들자고 생각해서 추가해야할 태그들을 만들었다.
let temp_html = `
<div class="col">
<div class="card h-100">
<div class="postData card-body" data-id="${doc.id}">
<h5 class="card-title">${name}</h5>
<p class="card-text">${comment}</p>
---> <div class="dbutton" class="d-grid gap-2 d-md-flex justify-content-md-end">
---> <button class="deleteBtn btn btn-outline-success me-md-2 btn-sm" type="button">삭제</button>
</div>
</div>
</div>
</div>`;
$('#card').append(temp_html);
카드에 삭제버튼을 추가해줬고
</div>
<div class="col-md">
<div class="form-floating">
<input type="password" class="form-control" id="pass" placeholder="비밀번호" maxlength="6">
<label for="floatingInputGrid">비밀번호를 입력하세요</label>
</div>
</div>
</div>
폼에 비밀번호 구역을 만들었다. input type을 passward로 하면 자동으로 바로 보이지 않돌고 된다.
이제 비밀번호 입력값을 DB에 넣는데
<script type = "module">
$("selector").click(async function () {
let name = $('#name').val();
let pass =$('#pass').val();
let comment = $('#comment').val();
let doc = {
'name': name,
'pass': pass, (반점 없으면 실행 안됨..)
'comment':comment
};
똑같이 대입해서 입력해줬다. 그리고 이제 DB에서 값을 가져왔다. 이런식으로(이렇게만 하면 안됨..)
let docs = await getDocs(collection(db, "firstteam"));
docs.forEach((doc) => {
let row = doc.data();
let name = row['name'];
let comment = row['comment'];
let pass = row['pass'];
그리고
let pass =${'#pass'} 해서 input값을 가져와서
console.log("test",pass);
console.log("pass",pass);
이런 식으로 했더니 게속 DB의 값이 잡히지 않았다. 구글링 해서 별의 별 방법을 써도 undefined가 뜨거나 아예오류가 나거나 빈칸으로 남아있었다.
알고보니 우리가 빈칸으로 떴을 때는 방명록 폼에 입력되어있는 값을 잡아온 것이거나 아예 잡히지 않은 것이었고 우선적으로 잡으려고 한다면. temp_html에 pass가 찍히게는 하되 보이지는 않게 하라는 튜터님의 말을 따라
let temp_html = `
<div class="col">
<div class="card h-100">
<div class="postData card-body" data-id="${doc.id}">
<h5 class="card-title">${name}</h5>
<p class="card-text">${comment}</p>
<p class="del" id="del">${pass}</p>
<div class="dbutton" class="d-grid gap-2 d-md-flex justify-content-md-end">
<button class="deleteBtn btn btn-outline-success me-md-2 btn-sm" type="button">삭제</button>
</div>
</div>
</div>
</div>`;
이런식으로 추가한 후에
$(".del").hide();
hide를 써서 숨겨주었다.
그리고 비밀번호를 입력할 수 있는 곳은 prompt를 이용해서 만들었다.
아무튼 이런저런 방법을 사용하다 결국 튜터님을 또 찾아갔다.
우리의 설명을 들은 튜터님은 결국 우리에게 뼈대를 만들어 주셨다.
$("#card").on("click", ".deleteBtn", async function () {
const inputPassword = prompt("패스워드를 입력해주세요.");
const cardElement =$ (this).closest(".card-body");
const storedPassword = cardElement.find("#del").text();
console.log("storedPassword", storedPassword);
console.log("inputPassword", inputPassword);
if (storedPassword == inputPassword) {
// 삭제처리
alert("성공적으로 삭제되었습니다.");
} else {
// 오류!
alert("비밀번호가 일치하지 않습니다.");
}
});
이런식으로 바꿔서 주셨다. 솔직히 설명은 이해가 갔지만 응용을 할 수 있을 진.. 모르겠다.
////우선 $('#card').on( "click","버튼 이름", async function(){ 이런 문법을 처음본다!!
정말 다양한 문법이 있구나 느낀다. .
이제 둘이서 삭제를 구현해야한다. 삭제를 구현하려면 필요한 것이
- 삭제할 카드 지정하기
- 삭제하기
우선 doc에서 문서를 끌고 오는 것을 했다.
let docs = await getDocs(collection(db, "firstteam"));
docs.forEach((doc) => {
let row = doc.data();
let name = row['name'];
let comment = row['comment'];
let pass = row['pass'];
let docId = doc.id;
let temp_html = `
<div class="col">
<div class="card h-100">
<div class="postData card-body" data-id="${doc.id}"> <----얜 뭘까
<h5 class="card-title">${name}</h5>
<p class="card-text">${comment}</p>
<p class="del" id="del">${pass}</p>
<p class="del" id="delid">${docId}</p>
<div class="dbutton" class="d-grid gap-2 d-md-flex justify-content-md-end">
<button class="deleteBtn btn btn-outline-success me-md-2 btn-sm" type="button">삭제</button>
</div>
</div>
</div>
</div>`;
$('#card').append(temp_html);
$(".del").hide();
중간에 튜터님이 오셔서 deleteDoc이란 것이 있으니 참고하라고 했다. 그대로 구글링을 했더니 firebase의 공식 문서가 나왔다.
https://firebase.google.com/docs/firestore/manage-data/delete-data?hl=ko
Cloud Firestore에서 데이터 삭제 | Firebase
Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 Cloud Firestore에서 데이터 삭제 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세
firebase.google.com
import { doc, deleteDoc } from "firebase/firestore";
await deleteDoc(doc(db, "cities", "DC"));
그대로 따와서 조건문 위에 붙였는데 계속 import랑 await 가 오류가 났다. deleteDoc에 들어있는 값들을 바꿔줬다.
await deleteDoc(doc(db, "컬렉션 이름", "문서이름")); 바꿔줘도 값은 똑같았다. console로 해도 값이 끌려오지 않았다. 그래서 튜터님을 또 찾아갔고 import의 자리를 알아냈다. 그리고 await를 쓸 때의 유의점을 알려주셨다.
import의 경우 위에 firebase세팅을 할 때 import 무리가 있었는데 그것들과 같이 쓰면 된다고 알려주셨고 await의 경우 그냥 쓰는게 아니라 function에 async을 꼭 넣어줘야한다고 말씀해주셨다. 더 자세하게는 javascript를 배울 때 알아가면된다고 하셨다. 그리고 다른 사이트를 알려주셨는데
https://softauthor.com/firebase-firestore-delete-document-deletedoc/
Firebase V9 Firestore DELETE Document Using deleteDoc()
Learn how to delete a document from a collection in Firebase version 9 Cloud Firestore using the deleteDoc() method.
softauthor.com
그렇게 돌아와서 다시 손을 보는데도 잘 되지 않았다. 여전히 정보가 끌어와지지 않았다. 나중에 알고보니 import를 완전히 잘못하고 있었다 . 중복된 부분이 있었다. 그리고 우리가 가져온 것은from 뒤가 url이 아니었는데 아래와 같이 되었어야하는 것이다. 그래서 위에 중복된 부분에 doc, deleteDoc을 추가해서 진행했다.
import { getFirestore, doc, deleteDoc } from "https:/
그 뒤로는 다시 연구해보며 하는데 많은 도움 끝에 해냈다.
const delpass = cardElement.find("#delid").text();
const docRef = doc(db, "firstteam", delpass);
if (storedPassword == inputPassword) {
// 삭제처리
alert("성공적으로 삭제되었습니다.");
await deleteDoc(docRef);
window.location.reload();
} else {
// 오류!
alert("비밀번호가 일치하지 않습니다.");
}
});
문서의 이름을 비밀번호 같이 카드에 넣고 숨겨준다음에 id값을 줘서 새롭게 정의를 해주었다. 그런다음에 문서이름을 넣었던 곳에 delpass를 넣어줬더니 잘 되었다.
삭제를 구현한 뒤에 input에 필수입력값을 주기로 했는데 구글링을 해보니 required를 이용하면 된다길래 바로 적용을 해봤다.
<form>안에 넣고 required를 적어줬는데 내가 원하는 대로가 아니라 그냥 빈칸이면 "입력해야한다~" 이런 멘트만 뜨지 액션을 멈추는 것은 아니라서 빈칸으로도 저장이 되고 있었다.
그래서 이번에도 튜터님을 찾아갔다.
$("#postingbtn").click(async function () {
let name = $('#name').val();
if (name === '') {
alert('성함을 입력해주세요!')
return;
}
let pass = $('#pass').val();
if (pass === '') {
alert('비밀번호를 입력해주세요!')
return;
}
let comment = $('#comment').val();
if (comment === '') {
alert('내용을 입력해주세요!')
return;
}
let doc = {
'name': name,
'comment': comment,
'pass': pass
};
await addDoc(collection(db, "firstteam"), doc);
alert('반가워요!')
window.location.reload();
})
이건 완성본인데 사실 구글링을 하다가 블로그에서 비슷한 식을 발견 했었는데
<script>
var name = document.getElementById("name").value;
if(name==''){
alert("이름을 입력해주십시오.");
$('#name').focus();
return false;
}
</script>
같은 의미 였는데 위치가 달라서 실행이 되지 않았던 것을..
처음엔 위치를 addDoc의 밑에 뒀었는데 확인들이 addDoc이 되기 전에 되야하는데 밑에 있어서 그냥 다 들어가버리더라.. 그래서 addDoc전에 실행되게 했더니 완료~!
아직은 솔직히 잘 모르겠지만 하나는 알겠다. 남들보다 더 노력해야 한다는 것을..
이번에 좀 더 구현해 보고 싶은 것은
1. 클릭하면 해당파트로 이동하는 것
2. 상단으로 올라가기
3. css좀더 예쁘게.
'개발일지' 카테고리의 다른 글
20231020 TIL 바닐라 자바스크립트 외부api 대입하기 (0) | 2023.10.20 |
---|---|
20231019 TIL 하루종일 뭐 했지. (0) | 2023.10.19 |
20231018 TIL 개인과제 시작! grid, overflow 사용 (1) | 2023.10.19 |
2023102nd WIL 데이터 타입, 연산자, 변수, 배열, 조건문, 반복문, 함수기초 (1) | 2023.10.17 |
20231005 TIL (id와class차이/ live server활용/ 사진 및 페이지 연결 등) (1) | 2023.10.11 |