[spring] 화면 처리 - 3

업데이트:



조회 페이지와 이동

조회 페이지 작성

조회 페이지는 입력 페이지와 거의 유사하지만 bno가 출력 된다는 점, 모든 데이터가 읽기 전용으로 처리된다는 점이 가장 큰 차이다.


참고로 게시글의 조회는 BoardController에서 get() 메서드로 구성되어있다.

@GetMapping("/get")
public void get(@RequestParam("bno") Long bno, Model model) {
    log.info("/get");
    model.addAttribute("board", service.get(bno));
}


views/board 폴더 내 get.jsp를 register.jsp를 복사해서 작성한다.

화면처리1


굳이 새 파일을 만들 필요없이 register.jsp를 클릭 후 컨트롤+c, 컨트롤+v를 누르면 팝업 창이 하나 뜨는데 거기에 get.jsp를 입력하면 board 폴더 내에 register.jsp 내용이 복사된 get.jsp가 생성된다.

<!-- get.jsp 수정 -->

<div class="row">
	<div class="col-lg-12">
		<h1 class="page-header">Board Read</h1>
	</div>
	<!-- /.col-lg-12 -->
</div>
<!-- /.row -->

<div class="row">
	<div class="col-lg-12">
		<div class="panel panel-default">

			<div class="panel-heading">Board Read Page</div>
			<!-- /.panel-heading -->
			<div class="panel-body">

                <div class="form-group">
                        <label>Bno</label> <input class="form-control" name="bno"
                            value='<c:out value="${board.bno}" />' readonly="readonly">
                </div>
            
            
                <div class="form-group">
                    <label>Title</label> <input class="form-control" name="title"
                    value='<c:out value="${board.title}" />' readonly="readonly">
                </div>
                
                <div class="form-group">
                    <label>Text area</label>
                    <textarea rows="3" class="form-control" name="content"
                    readonly="readonly"><c:out value="${board.content}" /></textarea>
                </div>
                
                <div class="form-group">
                    <label>Writer</label> <input class="form-control" name="writer"
                    value='<c:out value="${board.writer}" />' readonly="readonly">
                </div>

                <button data-oper='modify' class="btn btn-default">Modify
                    Button</button>
                <button data-oper="list" class="btn btn-info">List</button>
				


브라우저에서 확인할 때 주소창 get뒤에 쿼리스트링 bno=1과 같이 붙여서 작성해야한다.

화면처리2


화면 하단의 버튼에 이동 링크를 추가한다.

<!-- get.jsp -->

<button data-oper='modify' class="btn btn-default"
    onclick="location.href='/board/modify?bno=<c:out value="${board.bno}"/>'">Modify
    </button>
<button data-oper="list" class="btn btn-info"
    onclick="location.href='/board/list'">List</button>





목록 페이지와 뒤로 가기 문제

목록에서 조회 페이지로의 이동

조회 페이지로 이동하는 방식은 자바스크립트를 이용해서 처리할 수도 있고, a 태그를 이용해서 처리 가능하다. 여기서는 a 태그를 이용해 이동한다.

list.jsp를 수정한다.


<c:forEach items="${list}" var="board">
        <tr>
        <td><c:out value="${board.bno}" /></td>
        <td><a href='/board/get/?bno=<c:out value="${board.bno}" />'>
        <c:out value="${board.title}" /></a></td>
        <td><c:out value="${board.writer}" /></td>
        <td><fmt:formatDate pattern="yyyy-MM-dd" 
        value="${board.regdate}" /></td>
        <td><fmt:formatDate pattern="yyyy-MM-dd" 
        value="${board.updateDate}" /></td>
    </tr>
</c:forEach>


브라우저에서 확인하면 게시글 제목에 링크가 걸려있는 걸 확인할 수 있다. 만약 게시글 상세 조회 페이지를 새창에서 보고 싶으면 target='_blank'를 지정하면 된다.



뒤로 가기 문제

페이지 이동을 등록 -> 모달 -> 목록 -> 조회 페이지에서 뒤로 가기를 누르면 모달창으로 이동하는 문제가 있다.

이 문제를 해결하려면 window의 history 객체를 이용해서 현재 페이지는 모달창을 띄울 필요가 없다고 표시를 해 두는 방식을 이용해야한다. 참고로 window의 history 객체는 스택 구조로 동작한다.

<!-- list.jsp 스크립트 부분 -->

<script type="text/javascript">
	$(document).ready(
			function() {
				var result = '<c:out value="${result}"/>';
				checkModal(result);

				history.replaceState({}, null, null);

				function checkModal(result) {
					if (result === '' || history.state) {
						return;
					}

					if (parseInt(result) > 0) {
						$(".modal-body").html(
								"게시글  " + parseInt(result) + "번이 등록되었습니다.");
					}
					$("#myModal").modal("show");
				}

				$("#regBtn").on("click", function() {
					self.location = "/board/register";
				});
			});
</script>


기존과 달라진 점은 history.replaceState() 부분과 checkModal()에서 history.state를 체크하는 부분이다. JavaScript의 처리는 우선 checkModal()을 실행하는데, 만일 등록된 후에 이동한 것이라면 모달창이 보이게 된다.

모달창이 보이는 여부와 관계없이 JavaScript의 모든 처리가 끝나게 되면 history에 쌓이는 상태는 모달창을 보여줄 필요가 없는 상태가 된다.





게시물의 수정/삭제 처리

수정/삭제 페이지로 이동

BoardController에서 get() 메서드를 수정한다.

@GetMapping({"/get", "/modify"})
public void get(@RequestParam("bno") Long bno, Model model) {
    log.info("/get or modify");
    model.addAttribute("board", service.get(bno));
}


views 폴더 내 modify.jsp를 작성한다. modify.jsp는 get.jsp와 같지만 수정이 가능한 ‘제목’이나 ‘내용’ 등이 readonly 속성이 없도록 작성한다.

<form role="form" action="/board/modify" method="post">

    <div class="form-group">
            <label>Bno</label> <input class="form-control" name="bno"
                value='<c:out value="${board.bno}" />' readonly="readonly">
    </div>


    <div class="form-group">
        <label>Title</label> <input class="form-control" name="title"
        value='<c:out value="${board.title}" />'>
    </div>
    
    <div class="form-group">
        <label>Text area</label>
        <textarea rows="3" class="form-control" name="content"><c:out value="${board.content}" /></textarea>
    </div>
    
    <div class="form-group">
        <label>Writer</label> <input class="form-control" name="writer"
        value='<c:out value="${board.writer}" />' readonly="readonly">
    </div>

    <div class="form-group" style="display:none">
        <label>RegDate</label> <input class="form-control" name="regDate"
            value='<fmt:formatDate pattern="yyyy/MM/dd" value="${board.regdate}" />'
            readonly="readonly">
    </div>

    <div class="form-group" style="display:none">
        <label>Update Date</label> <input class="form-control" name="updateDate"
            value='<fmt:formatDate pattern="yyyy/MM/dd" value="${board.updateDate}" />'
            readonly="readonly">
    </div>

    <button type="submit"  data-oper="modify" 
        class="btn btn-default">Modify</button>
    <button type="submit"  data-oper="remove" 
        class="btn btn-default">Remove</button>
    <button type="submit"  data-oper="list" 
        class="btn btn-default">List</button>
    
</form>

form 태그는 action 속성을 ‘/board/modify’로 지정했지만, 삭제를하면 ‘/board/remove’와 같이 action 속성의 내용을 수정해서 사용하게 된다. 등록일과 수정일은 나중에 BoardVO로 수집되어야 하므로 날짜 포맷을 ‘yyyy/MM/dd’로 맞춰줘야한다.

브라우저에서 수정 페이지가 정상적으로 출력되는지 확인한다. 참고로 등록일과 수정일이 안보이는 이유는 hidden 처리가 된 상황이라 그렇다.

화면처리3



이제 버튼에 따라 다른 동작을 할 수 있도록 modify.jsp의 스크립트 부분을 작성한다.

<script type="text/javascript">
$(document).ready(function(){
	
	var formObj = $("form");
	
	$('button').on("click", function(e){
		e.preventDefault();
		
		var operation = $(this).data("oper");
		
		console.log(operation);
		
		if(operation === 'remove'){
			formObj.attr("action", "/board/remove");
		}else if(operation === 'list'){
			//move to list
			self.location = "/board/list";
			return;
		}
		formObj.submit();
	});
});
</script>


자바스크립트에서는 button 태그의 data-oper 속성을 이용해서 원하는 기능을 동작하도록 처리한다. form 태그의 모든 버튼은 기본적으로 submit으로 처리하기 때문에 e.preventDefault()로 기본 동작을 막고 마지막에 직접 submit()을 수행한다.





게시물 수정/삭제 확인

화면에서 게시글을 수정 후 ‘modify’ 버튼을 눌러 BoardController에 수정을 요청한다.

수정이 정상적으로 처리되면 로그에서 확인할 수 있다.

INFO : org.zerock.controller.BoardController - /get or modify
INFO : org.zerock.controller.BoardController - modify: BoardVO(bno=20, title=수정테스트, content=수정테스트, writer=newbie, regdate=null, updateDate=Fri May 28 00:00:00 KST 2021)


게시글이 수정된 후에는 다시 ‘/board/list’ 화면으로 이동하게 된다.



화면에서 ‘Remove’ 버튼을 클릭하게 되면 form 태그의 action 값이 ‘/board/remove’가 되고 데이터들이 전송된다. 삭제처리가 성공적으로 완료되면 다음과 같은 로그를 확인할 수 있다.

INFO : org.zerock.controller.BoardController - remove.....20
INFO : org.zerock.controller.BoardController - list





조회 페이지에서 form 처리

기존에 작성했던 버튼에 링크를 처리하는 방식을 form 태그를 이용해서 수정한다.

<!-- get.jsp 일부 -->

<button data-oper='modify' class="btn btn-default">Modify</button>
<button data-oper="list" class="btn btn-info">List</button>

<form id='operForm' action="/board/modify" method="get">
    <input type='hidden' id='bno' name='bno' value='<c:out value="${board.bno}"/>'>
</form>

... 생략

<script type="text/javascript">
$(document).ready(function(){
	
	var operForm = $("#operForm");
	
	$("button[data-oper='modify']").on("click", function(e){
		operForm.attr("action", "/board/modify").submit();
	});
	
	$("button[data-oper='list']").on("click", function(){
		operForm.find("#bno").remove();
		operForm.attr("action", "/board/list")
		operForm.submit();
	});
});
</script>





수정 페이지에서 링크 처리

수정 페이지에서 다시 목록 페이지로 이동할 수 있도록 하기 위해 자바스크립트를 수정한다.

<!-- modify.jsp -->

<script type="text/javascript">
$(document).ready(function(){
	var formObj = $("form");
	
	$('button').on("click", function(e){
		e.preventDefault();
		
		var operation = $(this).data("oper");
		
		console.log(operation);
		
		if(operation === 'remove'){
			formObj.attr("action", "/board/remove");
		}else if(operation === 'list'){
			//move to list
			formObj.attr("action", "/board/list").attr("method", "get");
			formObj.empty();
		}
		formObj.submit();
	});
});
</script>


‘/board/list’로의 이동은 아무런 파라미터가 없기 때문에 form 태그의 모든 내용은 삭제한 상태에서 submit()을 진행한다.

책에 있는 코드에는 없지만… 이후 코드는 실행되지 않도록 return을 통해 제어한다. 아마 formObj.empty(); 코드 밑에 return; 을 적어주면 될 줄 알았는데 return;을 적어주면 list 버튼 클릭 시 게시글이 아무것도 안보인다.







  • 참고 : 코드로 배우는 스프링 웹 프로젝트

태그:

카테고리:

업데이트:

댓글남기기