본문 바로가기
학원/spring

1.22 (tiles-댓글 작성, 목록 처리/더보기 버튼)

by 쿠룽지 2024. 1. 22.
728x90
반응형

 

 

<댓글 글자수 제한 구현>

 

 

 

댓글 등록 메서드 생성

BoardAjaxController

/*=============================
*    댓글 등록
============================*/
@RequestMapping("/board/writeReply")
@ResponseBody
public Map<String,String> writeReply(BoardReplyVO boardReplyVO,
                                    HttpSession session,
                                    HttpServletRequest request){
   log.debug("<<댓글 등록 BoardReplyVO>> : " + boardReplyVO);

   Map<String,String> mapJson = new HashMap<String,String>();

   MemberVO user = (MemberVO)session.getAttribute("user");
   if(user==null) {
       //로그인 안됨
       mapJson.put("result", "logout");
   }else {
       //회원번호 등록
       boardReplyVO.setMem_num(user.getMem_num());
       //ip 등록
       boardReplyVO.setRe_ip(request.getRemoteAddr());
       //댓글 등록
       boardService.insertReply(boardReplyVO);
       mapJson.put("result", "success");
   }
   return mapJson;
}

 

 

 

 

 

 

js 파일 생성

resources

static

js

board.reply.js (javaScript 생성)

/*----------------------
    댓글 등록, 수정 (공통)
------------------------*/		
//textarea에 내용 입력 시 글자수 체크
$(document).on('keyup','textarea',function(){
    //입력한 글자수 구하기
    let inputLength = $(this).val().length;

    if(inputLength>300){ //300자를 넘어선 경우
        $(this).val($(this).val().substring(0,300));
    }else{ //300자 이하인 경우
        //남은 글자수 구하기
        let remain = 300 - inputLength;
        remain += '/300';
        if($(this).attr('id')=='re_content'){
            //등록폼 글자수
            $('#re_first .letter-count').text(remain); //등록폼 제어
        }else if($(this).attr('id')=='mre_content'){
            //수정폼 글자수
            $('#mre_first .letter-count').text(remain);
        }
    }
});

1.
substring
문자열 자르기 함수
인자로 전달된 문자열의 부분을 잘라서 리턴

2.
remain += '/300'; 해서
남은글자수 /300 << 이렇게 보이게 함

 

 

 

 

 

 

reply 스크립트 추가하기

views

board

boardView.jsp

<!-- 내용 시작 -->
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.6.0.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/videoAdapter.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/board.fav.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/board.reply.js"></script>

1.
<script type="text/javascript" src="${pageContext.request.contextPath}/js/board.reply.js"></script>
js 링크 복붙

2.
실행하고 댓글창에 입력하면
300자에서 점점 줄어드는게 보임

아직 저장은 안됨

 

 

 

 

 


 

 

 

 

<댓글 등록 구현>

 

 

 

 

js 파일에 댓글등록 ajax 추가하기

js

board.reply.js

	/*----------------------
	        댓글 등록
	------------------------*/
	//댓글 등록
	$('#re_form').submit(function(event){
		if($('#re_content').val().trim()==''){
			alert('내용을 입력하세요');
			$('#re_content').val('').focus();
			return false;
		}
		
		//폼 이하에 있는 데이터 한번에 읽어오기
		let form_data = $(this).serialize();
		//서버와 통신
		$.ajax({
			url:'writeReply',
			type:'post',
			data:form_data,
			dataType:'json',
			success:function(param){
				if(param.result == 'logout'){
					alert('로그인해야 작성할 수 있습니다.');
				}else if(param.result == 'success'){
					//폼 초기화
					initForm();
					//댓글 작성이 성공하면 새로 삽입한 글을 포함해서
					//첫번째 페이지의 게시글들을 다시 호출
					selectList(1);
				}
			},
			error:function(){
				alert('네트워크 오류 발생');
			}
		});
		//기본 이벤트 제거
		event.preventDefault();
	});
	
	//댓글 작성폼 초기화
	function initForm(){
		$('textarea').val('');
		$('#re_first .letter-count').text('300/300'); //원상복귀
	}

1.
댓글등록 submit function의 인자가 event 여야지만 아래에 기본 이벤트를 제거할 수 있음
$('#re_form').submit(function(event){
event.preventDefault();

 

이 두 코드의 event << 가 있어야함


2.
실행하고 댓글 입력하면 오라클에 저장됨
목록에는 아직 출력 안됨

 

 

 

 

 


 

 

 

 

<댓글 목록 작업>

 

 

 

 

목록 sql문 작성하기

BoardMapper.xml

   <!-- 댓글 목록 -->
   <select id="selectListReply" parameterType="map" resultType="boardReplyVO">
   	SELECT
   	  *
   	FROM (SELECT
   			a.*,
   			rownum rnum
   		  FROM (SELECT
   		  		   re_num,
   		  		   <![CDATA[
   		  		   REPLACE(REPLACE(re_content,'<','&lt;'),'>','&gt;') re_content,
   		  		   ]]>
   		  		   re_date,
   		  		   re_mdate,
   		  		   board_num,
   		  		   mem_num,
   		  		   id,
   		  		   nick_name
   		  		FROM spboard_reply
   		  		JOIN spmember USING(mem_num)
   		  		WHERE board_num=#{board_num}
   		  		ORDER BY re_num DESC)a)
   	<![CDATA[
   	WHERE rnum >= #{start} AND rnum <= #{end}
   	]]>
   </select>

댓글 목록에서 가져올 것들 모두 기재

1.
selectListReply
BoardMapper.xml의 id는 BoardMapper.java 파일의 메서드명과 같아야함

2.
 REPLACE(REPLACE(re_content,'<','&lt;'),'>','&gt;') re_content
re_content 로 알리아스를 준거임

 

 

 

 

 

 

 

목록개수 구하기

BoardMapper.java

count는 짧아서 java에 명시

@Select("SELECT COUNT(*) FROM spboard_reply WHERE board_num=#{board_num}")
public int selectRowCountReply(Map<String,Object> map);

 

 

 

 

 

 

 

서비스 파일에서 호출하기

BoardServiceImpl

/*----------------댓글--------------------------*/

@Override
public List<BoardReplyVO> selectListReply(Map<String, Object> map) {
    return boardMapper.selectListReply(map);
}

@Override
public int selectRowCountReply(Map<String, Object> map) {
    return boardMapper.selectRowCountReply(map);
}

 

 

 

 

 

 

Ajax Controller 에서 코드 작성

BoardAjaxController

/*=============================
*    댓글 목록
============================*/  
@RequestMapping("/board/listReply")
@ResponseBody
public Map<String,Object> getList(@RequestParam(value="pageNum", defaultValue="1") int currentPage,
                                 @RequestParam(value="rowCount", defaultValue="10") int rowCount,
                                 @RequestParam int board_num, HttpSession session){
   log.debug("<<댓글 목록 board_num>> : " + board_num);

   Map<String,Object> map = new HashMap<String,Object>();
   map.put("board_num", board_num);

   //전체 레코드 수
   int count = boardService.selectRowCountReply(map);
   //페이지 처리 (더보기를 누를때 페이지가 보이는 형태 -> pageUtil은 start, end를 구하기 위해 연산하는 형태로만 쓰임)
   PageUtil page = new PageUtil(currentPage,count,rowCount);

   List<BoardReplyVO> list = null;
   if(count > 0) { // count>0 일 경우에만 연산 작업
       map.put("start", page.getStartRow());
       map.put("end", page.getEndRow());
       list = boardService.selectListReply(map);
   }else {
       list = Collections.emptyList();
   }

   Map<String,Object> mapJson = new HashMap<String,Object>();
   mapJson.put("count", count);
   mapJson.put("list", list);

   //로그인한 회원정보 셋팅
   MemberVO user = (MemberVO)session.getAttribute("user");
   if(user!=null) {
       mapJson.put("user_num", user.getMem_num());
   }
   return mapJson;
}

10개를 기본 댓글 수로 두고, 댓글 수가 그 이상을 넘어가면 더보기 버튼 생성 + 눌러야 그 뒤 항목이 보이는

화면을 생성할 것임

 

그래서 PageUtil도 별다른걸 주지 않고 start, end 페이지를 구하기 위해 연산하는 형태로만 썼음

 

1.
실질적으로 데이터를 보내는 것은
re_content, board_num 두가지
(나머지는 session에서 뽑아내거나 sysdate를 주거나 하는 것들)

2.
list = Collections.emptyList();
list를 비어있는 배열로 인식하게끔 함

 

 

 

 

 

 

 

 

js파일에서 ajax 코드 작성

board.reply.js

/*----------------------
        댓글 목록
------------------------*/
//댓글목록
function selectList(pageNum){
    currentPage = pageNum;
    //로딩 이미지 노출
    $('#loading').show();

    $.ajax({
        url:'listReply',
        type:'post',
        data:{pageNum:pageNum,rowCount:rowCount,board_num:$('#board_num').val()},
        dataType:'json',
        success:function(param){
            //로딩 이미지 감추기
            $('#loading').hide();
            count = param.count;

            //조건체크
            if(pageNum == 1){
                //처음 호출 시에는 해당 ID의 div의 내부 내용물을 제거
                $('#output').empty();
            }

            //댓글수 읽어오기
            displayReplyCount(param);

            //댓글 목록 작업 (item=한건의 레코드를 읽어옴)
            $(param.list).each(function(index,item){
                let output = '<div class="item">';
                output += '<ul class="detail-info">';
                output += '<li>';
                output += '<img src="../member/viewProfile?mem_num='+item.mem_num+'" width="40" height="40" class="my-photo">';
                output += '</li>';
                output += '<li>';

                if(item.nick_name){
                    output += item.nick_name + '<br>';
                }else{
                    output += item.id + '<br>';
                }

                if(item.re_mdate){
                    output += '<span class="modify-date">최근 수정일 : ' + item.re_mdate + '</span>';
                }else{
                    output += '<span class="modify-date">등록일 : ' + item.re_date + '</span>';
                }

                output += '</li>';
                output += '</ul>';
                output += '<div class="sub-item">';
                output += '<p>' + item.re_content.replace(/\r\n/g,'<br>') + '</p>';

                if(param.user_num==item.mem_num){
                    //로그인한 회원번호와 댓글 작성자 회원번호가 같으면
                    output += ' <input type="button" data-num="'+item.re_num+'" value="수정" class="modify-btn">';
                    output += ' <input type="button" data-num="'+item.re_num+'" value="삭제" class="delete-btn">';
                }

                output += '<hr size="1" noshade>';
                output += '</div>'; //end of sub_item
                output += '</div>'; //end of item

                //문서 객체에 추가
                $('#output').append(output);
            });

            //paging button 처리
            if(currentPage>=Math.ceil(count/rowCount)){
                //다음 페이지가 없음
                $('.paging-button').hide();
            }else{
                //다음 페이지가 존재
                $('.paging-button').show();
            }
        },
        error:function(){
            //로딩 이미지 감추기
            $('#loading').hide();
            alert('네트워크 오류 발생');
        }
    });
}

1.
img를 이용해서 viewProfile을 읽어오게 할거임 (mem_num값을 넘겨서 가져옴)

2.
sub-item > 내용 명시
item.re_content.replace(/\r\n/g,'<br>')
줄바꿈 처리는 해야하기 때문에 불허한걸 부분 허용



restart 후 게시판 들어가서 보면
목록에 제목(댓글수) 형식으로 보임 + 댓글도 표시됨

 

 

 

 

댓글 수 표시 부분도 추가

/*----------------------
    댓글수 표시
------------------------*/
function displayReplyCount(param){
    let count = param.count;
    let output;

    if(count>0){
        output = '댓글수('+count+')';
    }else{
        output = '댓글수(0)';
    }
    //문서 객체의 추가
    $('#output_rcount').text(output);
}

위 댓글 목록 처리 시
//댓글수 읽어오기
displayReplyCount(param); 
와 이름이 똑같은 함수 생성

 

본문 제목 쪽 좋아요 옆에 댓글 수도 함께 나옴

 

 

 

 

 

 

 

작성한 댓글이 10개가 넘어갔을 때 더보기 버튼 -> 10개의 댓글이 더 보이게 하기 위해 이벤트 연결

//다음 댓글 보기 버튼 클릭시 데이터 추가
$('.paging-button input').click(function(){
    selectList(currentPage + 1);
});

이제 더보기 누르면 댓글 더보기 동작이 됨
댓글 더보기 원리는 기존 댓글 데이터가 있는 곳에 숨겨진 댓글 데이터를 붙이는 것

 

 

 

728x90
반응형