코디잉
21_공동구매 게시물 상세보기 ② 댓글(목록, 등록, 수정, 삭제, 고정) 본문
① 공동구매에 관련된 정보들 가져오기
② 참여자목록 (참여자들 프로필사진 및 닉네임)
③ 댓글(등록, 수정, 삭제, 고정 처리)
④ 신고팝업, 신고처리(게시물, 댓글)
⑤ 찜(♡)
⑥ 버튼 관련
댓글 관련 작업 ㄱㄱ!
③ 댓글(목록, 등록, 수정, 삭제, 고정 처리)
③-1) 댓글 목록
- 댓글은 모든 회원이 등록할 수 있다.
- 댓글 고정은 해당 공동구매의 진행자만 본인의 댓글 1개를 제일 상단으로 고정시키는 기능으로,
자신의 댓글을 고정 혹은 고정해제를 할 수 있다.
- 본인이 쓴 댓글은 수정 / 삭제가 가능하고, 타회원이 쓴 댓글은 신고할 수 있다.
그래서 회원이 해당 공동구매의 진행자인지, 참여자인지를 구분해야 한다.
세션에 있는 멤버코드와 댓글의 멤버코드, 공동구매 작성자 멤버코드를 비교했다.
1) 본인의 댓글이라면,
1-1) 진행자라면,
1-1-1) 고정한 댓글 → 고정취소/수정/삭제
1-1-2) 고정하지 않은 댓글 → 고정/수정/삭제
1-2) 진행자아닌 다른 회원 → 수정/삭제
2) 본인 댓글 아니라면, → 신고 기능을 할 수 있어야 한다.
위의 분기 내용을 코드로 작성한 것이다.
<c:forEach var="reply" items="${replyList }">
<div class="d-flex mb-4 reply-box">
<div class="buypost_profile_photo reply-profile-photo">
<img src="img/mannerLevel/${reply.photo_name }" />
</div>
<div class="reply">
<!-- 닉네임 -->
<c:choose>
<%-- 진행자 --%>
<c:when test="${reply.member_code == buypost.member_code }">
<span class="pin-nickname">${reply.nickname }</span>
<c:if test="${not empty reply.reply_fix }">
<i class="bi bi-pin-fill"></i>
</c:if>
</c:when>
<%-- 그 외 --%>
<c:otherwise>
${reply.nickname }
</c:otherwise>
</c:choose>
<!-- 댓글 기능 -->
<div class="fw-bold reply-nickname">
<c:choose>
<%-- ① 진행자 --%>
<c:when test="${member_code == buypost.member_code && member_code == reply.member_code}">
<c:choose>
<%-- 1) 고정 댓글 --%>
<c:when test="${not empty reply.reply_fix }">
<div class="reply-control">
<a class="reply-pin-cancel" href="#!">고정취소</a> | <a
class="reply-update" href="#!">수정</a> | <a
class="reply-delete" href="#!">삭제</a>
</div>
</c:when>
<%-- 2) 고정하지 않은 댓글 --%>
<c:otherwise>
<div class="reply-control">
<a class="reply-pin-cancel" href="#!">고정하기</a> | <a
class="reply-update" href="#!">수정</a> | <a
class="reply-delete" href="#!">삭제</a>
</div>
</c:otherwise>
</c:choose>
</c:when>
<%-- ② 진행자 외 타회원 --%>
<c:otherwise>
<c:choose>
<%-- 1) 본인 댓글 --%>
<c:when test="${member_code == reply.member_code }">
<div class="reply-control">
<a class="reply-update" href="#!">수정</a> | <a class="reply-delete" href="#!">삭제</a>
</div>
</c:when>
<%-- 2) 타회원 댓글 --%>
<c:otherwise>
<div class="reply-control">
<a class="report reply-report" href="javascript:report()">신고</a>
</div>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>
</div>
<!-- 댓글내용 -->
<div class="reply-content-box">
<span class="reply-text">${reply.content }</span>
</div>
</div>
</div>
</c:forEach>
🔥 jsp 변수(여기서는 세션에 저장해놓은 멤버코드) 를 jstl 태그 안에서 그냥 ${member_code} 하면 불러와짐!
진행자의 닉네임은 다른 색으로 표시되게 했고, 진행자의 고정댓글에는 닉네임 옆에 핀셋 표시를 했다.
코드 처리를 마친 딸기 공동구매 게시물의 댓글 목록을 보면,
1) 진행자 화면 (닉네임: berry)
본인 댓글 중 고정해놓은 댓글에는 고정취소/수정/삭제 처리가 가능하고,
고정하지 않은 댓글은 고정하기/수정/삭제 처리가 가능하게 되어있다.
그리고 타회원의 댓글은 신고할 수 있도록 되어있다.
2) 작성한 댓글이 있는 회원의 화면 (닉네임: 용짱)
본인의 댓글은 수정/삭제할 수 있고, 타회원 댓글은 신고할 수 있게 되어있다.
3) 댓글달지 않은 회원 혹은 비회원
③-2) 댓글 등록
댓글 <등록> 버튼을 눌렀을 때, 댓글 내용이 없거나, 공백만 있다면 메세지를 띄우기 위한 JS코드
정상적으로 댓글 입력했으면 폼을 제출한다.
// 댓글 등록
$('.reply-btn').click(function()
{
$('#replyErrMsg').css('display', 'none');
let content = $.trim($('.reply-insert-form').val());
if (content == '')
$('#replyErrMsg').css('display', 'block');
else
$('#replyInsertForm').submit();
});
컨트롤러에서는 insert 쿼리 실행 후, 공동구매 게시물을 다시 불러주면서 !공동구매코드를 같이 넘겨준다!
IBuypostDAO dao = sqlSession.getMapper(IBuypostDAO.class);
dao.insertReply(reply);
return "redirect:buypostarticle.lion?code=" + reply.getBuypost_code();
비회원은 댓글을 달 수 없으므로, 비회원이 댓글을 등록하려고 하면 로그인폼으로 이동시키고 안내팝업을 띄워준다.
댓글 내용이 없거나, 공백만 있다면 '내용을 입력해주세요'라는 메세지를 띄워준다.
정상적으로 댓글을 달면, 댓글이 등록된 걸 확인할 수 있다.
③-3) 댓글 수정
🔥 <a> 태그 눌러도 새로고침 안되게 하기 → href="javascript:return false;"
🔥 <a> 태그에 value값 주기 → data-value 속성 사용하면된다. jquery 로 값 불러올 때는
『data-』는 떼고 뒤에 붙인 이름으로 값 가져오면 된다.
--html 코드
<a class="reply-update" href="javascript:return false;" data-value="${reply.code }">수정</a>
--jquery 코드
let id = $(this).data('value');
🔥 jquery 자식 요소 선택하기 → children()
$('.reply').children('.reply-content-update-box').css("display", "block");
🔥 jquery 자손 요소 선택하기 → find()
$('.reply').find('.reply-control').css("display", "none");
<수정> 부분에서 작성한 스크립트 코드는
- 해당 댓글의 [수정]을 클릭하면, 해당 댓글의 수정폼 보여주기
- 수정도 등록과 똑같이 공란이거나 공백만 있다면, 에러메세지를 띄워주기
// <수정>: 댓글 수정폼 뜨게
$(".reply-update").click(function()
{
// 댓글 에러 메세지 안보이게
$('#replyErrMsg').css('display', 'none');
// 댓글 수정폼 안뜨게
$(".reply-content-box").css("display", "block");
$('.reply-control').css("display", "block");
$(".reply-content-update-box").css("display", "none");
let id = $(this).data('value');
$('#'+id).children('.reply-content-box').css("display", "none");
$('#'+id).find('.reply-control').css("display", "none");
$('#'+id).children('.reply-content-update-box').css("display", "block");
});
// <수정>: form 제출
$(".reply-updateBtn").click(function()
{
let id = $(this).val();
let updateContent = $.trim($('#'+id).find('.reply-update-form').val());
if (updateContent == "" || updateContent == '' || updateContent == null)
$('#'+id).find('#replyUpdateErrMsg').css('display', 'block');
else
$('#'+id).find('#replyUpdateForm').submit();
});
수정폼에서 UPDATE 쿼리문에 필요한 해당 댓글코드와 redirect할 때 필요한 공동구매 코드는 hidden type으로 넘겨줬다.
<div class="reply-content-update-box">
<form class="mb-4" id="replyUpdateForm" action="<%=cp%>/updatebuypostreply.lion">
<textarea name="content" class="form-control reply-form reply-update-form" rows="3"
placeholder="댓글을 입력해주세요." >${reply.content }</textarea>
<button type="button" class="primary-btn reply-btn reply-updateBtn" value="${reply.code }">수정</button>
<div class="errMsg" id="replyUpdateErrMsg">내용을 입력해주세요.</div>
<input type="hidden" name="code" value="${reply.code }"/>
<input type="hidden" name="buypost_code" value="${buypost.code }"/>
</form>
</div>
컨트롤러에서는 INSERT 때와 동일하게 UPDATE 쿼리 실행 후, hidden 값으로 넘겨줘서 받은 공동구매 코드를 사용해서
공동구매게시물로 redirect 시켜주었다.
IBuypostDAO dao = sqlSession.getMapper(IBuypostDAO.class);
dao.updateReply(reply);
return "redirect:buypostarticle.lion?code=" + reply.getBuypost_code();
세션에 멤버코드값이 없다면(로그아웃상태 or 비회원), <수정>버튼을 눌렀을 때, 로그인폼으로 안내해주며 로그인 후 사용가능하다는 안내 팝업을 띄워주는건 <등록> 때와 동일하다.
[수정 | 삭제] 버튼 위치!
본인 댓글 옆 [수정]을 클릭했을 때 나오는 수정폼이다. 본인이 썼던 내용이 입력되어 있다.
입력 댓글 내용이 없거나, 공백만 있다면 '내용을 입력해주세요'라는 메세지를 띄워준다.
정상적으로 댓글을 수정한 뒤, <수정> 버튼을 클릭했을 때 결과!!
③-4) 댓글 삭제
DELETE 쿼리에서는 댓글 코드가 필요하고, redirect 해주기 위해서 공동구매 코드가 필요하니 이번에는 주소값으로 그냥 넘겨주는 방식으로 ㄱㄱ!
이미 공동구매 상세보기 페이지 주소값에는 공동구매 코드가 있으므로 그거 가져오고, 댓글코드는 수정에서 했던것처럼 <a>태그의 data-value로 ${reply.code}를 넣어놓은 걸 가져왔다.
<!-- HTML 코드 -->
<a class="reply-delete" href="javascript:return false;" data-value="${reply.code }">삭제</a>
// jQuery 코드
$('.reply-delete').click(function()
{
let buypost_code = '<%=request.getParameter("code")%>';
let reply_code = $(this).data('value');
location.href = 'deletebuypostreply.lion?buypost=' + buypost_code + "&reply=" + reply_code;
});
이번에 삭제할 체크!
삭제 버튼을 누르면 정상적으로 삭제된 걸 확인할 수 있다.
③-5) 댓글 고정 / 고정취소
댓글에서 마지막,,! 공동구매 진행자가 본인의 댓글을 댓글 목록 최상단으로 고정하기 혹은 고정된 댓글을 고정해제 하는 것이다.
이미 고정된 댓글이 있는데, 본인의 다른 댓글에서 <고정하기>를 누르면, 원래 고정되어 있던 댓글은 고정해제되고, 해당 댓글이 최상단으로 고정되게 처리할 예정!
.......
ㅎ...고정하려다 갑자기 목록부터 고치느라 오래걸렸다....
현재 ERD 구성은 댓글테이블 - 댓글고정테이블이 따로 있는 상태이다.
댓글테이블에 고정여부에 관한 컬럼을 놔두면 고정할 때마다 계속 업데이트를 시켜줘야 하니까, 따로 고정 로그를 기록하는 테이블을 생성했다.
그런데 테이블 이렇게 짜놓은거 생각안하고 위에서 댓글 목록 가져올 때 고정여부컬럼을 사용한 것처럼 쿼리를 짜서 수정했다..!
뭔가 쿼리 지저분한 거 같기는 한데,,일단,,!
고정된 걸 상단에 띄워주고 UNION ALL 나머지 목록들 띄우는 방식으로 쿼리를 작성했다.
--댓글 목록 재작성
SELECT *
FROM VIEW_REPLYLIST
WHERE REPLY_FIX = (SELECT MAX(REPLY_FIX) FROM VIEW_REPLYLIST WHERE BUYPOST_CODE = 'BP256')
UNION ALL
SELECT *
FROM VIEW_REPLYLIST
WHERE BUYPOST_CODE = 'BP256'
AND (NOT REPLY_FIX IN (SELECT MAX(REPLY_FIX) FROM VIEW_REPLYLIST WHERE BUYPOST_CODE = 'BP256')
OR REPLY_FIX IS NULL)
댓글 <고정하기> 를 누르면, 주소값으로 댓글코드와 공동구매코드를 넘겨주었다.
<a class="reply-pin-cancel" href="fixbuypostreply.lion?buypost=${reply.buypost_code}&reply=${reply.code}">고정하기</a>
그럼 진행자의 다른 댓글에 <고정하기>를 눌러보자
고정해제 댓글은 썼던 시간 순서대로 목록에 자리잡고, 고정댓글은 최상단으로 가야한다.
새로 댓글 고정 후 화면이다.
고럼 이제 마지막 <고정취소>
방금 고정해놓은 댓글 <고정취소> 할 경우, 아무것도 고정된 댓글 없이 그냥 작성시간 순서로 목록이 뜨면 된다.
고정할 때마다 댓글고정테이블에 insert 시켜주고, 고정할 댓글을 가져올 때 해당 고정테이블 시퀀스의 가장 큰 값을 가져오도록 쿼리를 작성해놨기 때문에
<고정취소>를 눌렀을 때 해당 컬럼만 제거해주면 그 전에 고정했던 댓글이 목록에 고정될 것이다.
그래서 해당 공동구매 고정테이블 기록을 다 지우도록 쿼리를 작성했다.
그래서 공동구매 코드만 주소로 넘겨주었다.
고정취소한 결과화면이다!
댓글,,, 끄읕,..........!!

'PROJECT > 같이사자(공동구매)' 카테고리의 다른 글
23_공동구매 게시물 상세보기 ④ 찜(♡) (0) | 2022.09.06 |
---|---|
22_공동구매 게시물 상세보기 ③ 신고(팝업, 게시물/댓글신고) (0) | 2022.09.06 |
20_공동구매 게시물 상세보기 ① 게시물정보/참여자목록 (0) | 2022.09.04 |
19_메인 > 지도 API & 선택 지역 세션 저장 (0) | 2022.09.01 |
18_공동구매 목록 ④ 검색 (0) | 2022.09.01 |