1102

이민규·2023년 11월 2일
0

Comments Post

  • 각 게시물에 첨부하는 댓글에 관한 제반 사항

DataBases

DB

create table mbanswer(idx smallint auto_increment primary key,
num smallint,
name varchar(20),
myid varchar(30),
content varchar(500),
writeday datetime,
foreign key(num) references memboard(num) on delete cascade);
  • num은 첨부 대상 게시물의 시퀀스이므로 foreign key로 연결하고 on delete cascade 조건 추가
  • 댓글 자체의 시퀀스는 idx

Mapper

@Mapper
public interface AnswerMapperInter {

	public void insertMbanswer(MbanswerDto dto);
	public List<MbanswerDto> getAllAnswers(String num);
	public MbanswerDto getAnswer(String idx);
	public void updateAnswer(MbanswerDto dto);
	public void deleteAnswer(String idx);
}
  • 댓글 관련 Sql문을 교환할 Mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="boot.data.mapper.MbanswerMapperInter">
	<insert id="insertMbanswer" parameterType="mbdto">
		insert into mbanswer values(null,#{num},#{name},#{myid},#{content},now())
	</insert>
	<select id="getAllAnswers" parameterType="String" resultType="mbdto">
		select * from mbanswer where num=#{num} order by idx desc
	</select>
	<select id="getAnswer" parameterType="String" resultType="mbdto">
		select * from mbanswer where idx=#{idx}
	</select>
	<update id="updateAnswer" parameterType="mbdto">
		update mbanswer set content=#{content} where idx=#{idx}
	</update>
	<delete id="deleteAnswer" parameterType="String">
		delete from mbanswer where idx=#{idx}
	</delete>
</mapper>
  • 댓글은 게시물에 첨부되는 데이터이므로, 게시물의 시퀀스(num)와 댓글의 시퀀스(idx)를 잘 구별하여야 함

Comment List

JavaScript

$(function(){
		list();
});

function list(){
	var s="";
	num=$("#num").val();
	var loginok="${sessionScope.loginok}";
	var myid="${sessionScope.myid}";
	
	$.ajax({
		data:{"num":num},
		dataType:"json",
		type:"get",
		url:"/mbanswer/alist",
		success:function(res){
			$.each(res,function(i,e){
				s+="<b>"+e.name+"("+e.myid+") : </b>";
				s+="<span check='check'>"+e.content+"</span>&nbsp;&nbsp;";
				if(loginok!=null&&myid==e.myid){
					s+="<i class='bi bi-recycle amod' idx='"+e.idx+"'></i>&nbsp;";
					s+="<i class='bi bi-trash-fill adel' idx='"+e.idx+"'></i><br>";
				}else{
					s+="<br>";
				}
			});
			$("div.alist").html(s);
			$("span.acount").text(res.length);
		}
	});
}
  • DB에 존재하는 댓글 중 게시물에 해당하는 모든 댓글을 출력하는 함수 (list())
    • 해당 파일이 구동되는 동시에 댓글이 출력되어야 하므로 기본적으로 해당 함수 작동
    • 게시물을 식별할 시퀀스 전달 (num)
  • JavaScript에서 Java의 Session을 사용하기 위해서는 JSTL의 EL(${ })과 sessionScope를 사용하되, 문자열 형태로 호출 가능
  • 출력할 내용 : 댓글 내용, 수정 버튼, 삭제 버튼, 댓글 개수
    • 수정, 삭제 버튼은 자신이 작성한 댓글에만 조건부로 출력 (if())
    • <br>의 위치가 조건부에 따라 달라지므로 유의
    • Ajax를 통해 돌아오는 데이터가 List<dto>이므로 반복 함수($.each() : 각 댓글 정보)의 인자 데이터를 사용할지, 반복되는 개별 데이터(dto, e : 댓글 전체 정보)를 사용할지 유의

Ajax Controller

@Controller
@RequestMapping("/mbanswer")
public class MbanswerController {

	@Autowired
	MbanswerMapperInter mapper;

	@GetMapping("/alist")
	public @ResponseBody List<MbanswerDto> list(@RequestParam String num){
		return mapper.getAllAnswers(num);
	}
}

Comments Insert

View_Insert Form

<!-- 댓글 -->
<tr>
	<td>
		<div class="alist"></div>
		<input type="hidden" id="num" value="${dto.num }">
		<c:if test="${sessionScope.loginok!=null }">
			<div class="aform">
				<div class="d-inline-flex">
					<input type="text" class="form-control" id="content">&nbsp;&nbsp;
					<button type="button" id="btnasnweradd">등록</button>
				</div>
			</div>
		</c:if>
	</td>
</tr>
  • 게시물 상세 페이지의 일부 (댓글 입력 파트)
  • 어떤 게시물에 첨부된 댓글인지를 구분할 게시물의 시퀀스인 numhidden으로 입력

Event_JavaScript

$(function(){
	list(); //전체 댓글 기본 출력용 함수
	
	$("#btnasnweradd").on("click",function(){
		var num=$("#num").val();
		var content=$("#content").val();
		
		if(content==""){
			alert("댓글을 입력해주세요");
			return;
		}else{
			$.ajax({
				data:{"num":num,"content":content},
				dataType:"html",
				type:"post",
				url:"/mbanswer/ainsert",
				success:function(res){
					$("#content").val("");
					list();
				}
			});
		}
	});
});
  • 삽입 후에는 댓글 입력 창 초기화 및 삽입한 댓글 포함한 전체 댓글 리스트 출력(list())
  • 공백 댓글 시 입력 반려

Controller

@Controller
@RequestMapping("/mbanswer")
public class MbanswerController {

	@Autowired
	MbanswerMapperInter mapper;
	
	@PostMapping("/ainsert")
	public @ResponseBody void insert(@ModelAttribute("mbdto") MbanswerDto mbdto,
			HttpSession session) {

		String check=mbdto.getContent().trim();
		if(!check.equals("")) {
			mbdto.setMyid((String)session.getAttribute("myid"));
			mbdto.setName((String)session.getAttribute("loginname"));
			mapper.insertMbanswer(mbdto);
		}
	}
}
  • 띄어쓰기를 포함한 공백 입력 시 입력 반려

Comment Delete

View

  • 동적 이벤트로 생성된 버튼을 통해 작동

Event_JavaScript

$(function(){

	$(document).on("click","i.adel",function(){
		var idx=$(this).attr("idx");
		
		$.ajax({
			data:{"idx":idx},
			dataType:"html",
			type:"post",
			url:"/mbanswer/adelete",
			success:function(res){
				list();
			}
		});
	});
});
  • Ajax 이벤트 완료 후 항상 변경 사항 포함한 리스트 재출력 (list())
  • 삭제용 Mapper(Sql), Controller 생략

Comment Update Form

View

  • 동적 이벤트로 생성된 버튼을 통해 작동

Event_JaveScript

$(function(){
	$(document).on("click","i.amod",function(){
		var content=$(this).prev().text();
		var idx=$(this).attr("idx");
		var check=$(this).prev().attr("check");
		
		if(check=="check"){
			$(this).prev().remove();
			$(this).hide();
			$(this).next().hide();
			
			$("#content").hide();
			$("#btnasnweradd").hide();
			
			var s="";
			s+="<div class='d-inline-flex'>";
			s+="<span>댓글 수정</span>";
			s+="<input type='text' id='modacontent' class='form-control' value='"+content+"' autofocus='autofocus'>&nbsp;";
			s+="<button type='button' class='btn btn-outline-warning' id='modclear' idx='"+idx+"'>수정완료</button>";
			s+="</div>";
			
			$(this).before(s);
		}
	});
});
  • DB의 댓글 내용을 미리 확보 후, 내용을 포함하는 태그 제거
    • 댓글 수정 작업하는 동안은 기존 댓글 작성창은 비활성화 (hide())
  • 동적 이벤트로 수정할 내용을 입력할 창과 수정된 내용을 이벤트로 등록할 버튼 동적 생성

Comment Update

Event_JavaScript

$(function(){

	$(document).on("click","#modclear",function(){
		var idx=$(this).attr("idx");
		var content=$(this).prev().val();
		
		$.ajax({
			data:{"idx":idx,"content":content},
			dataType:"html",
			type:"post",
			url:"/mbanswer/aupdate",
			success:function(res){
				list();
				$("#content").show();
				$("#btnasnweradd").show();
			}
		});
	});
});

Controller

@Controller
@RequestMapping("/mbanswer")
public class MbanswerController {

	@Autowired
	MbanswerMapperInter mapper;

	@PostMapping("/aupdate")
	public @ResponseBody void update(String idx,String content) {
		
		MbanswerDto mbdto=mapper.getAnswer(idx);
		mbdto.setIdx(idx);
		mbdto.setContent(content);
		
		mapper.updateAnswer(mbdto);
	}
}
profile
초보개발자

0개의 댓글