Keep going

화면 처리 본문

Records/Spring Framework

화면 처리

코딩천재홍 2021. 2. 21. 02:18

11.1 목록 페이지 작업과 includes

스프링 MVC 의 JSP 를 처리하는 설정은 servlet-context.xmll에 아래와 같이 작성되어 있다.

 

Servlet-context의 일부
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
    <resources mapping="/resources/**" location="/resources/" />
 
    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>
cs

스프링 MVC의 설정에서 화면 설정ViewResolver라는 객체를 통해 이루어지는데,

위의 설정을 보면 /WEB-INF/views 폴더를 이용하는 것을 볼 수 있다.

/WEB-INF 경로는 브라우저에서 직접 접근할 수 없는 경로이므로 반드시 Controller를 이용하는 모델 2방식에서는 기본적으로 사용하는 방식이다.

게시물 리스트의 URL은 /board/list 이므로 최종적인 /WEB-INF/views/board/list.jsp가 된다.

 

 

11.1.1 SB Admin2 페이지 적용하기

정상적으로 /board/list 페이지가 동작한다면 SB Admin2의 pages 폴더에 있는 tables.html의 내용을 list.jsp의 내용으로 그대로 복사해서 수정하고 실행한다.

SB Admin2 의 CSS 경로는 http://localhost:8080/vendor/bootstrap/css/bootstrap.min.css 경로이므로 현재 프로젝트에서는 제대로 서비스 될 수 없다.

정적인 자원들의 경로를 'resources'라는 경로로 지정하고 있다.

SB Admin2의 압축을 풀어둔 모든 폴더를 프로젝트 내 webapp 밑의 resources 폴더로 복사해 넣는다.

파일들을 resources 경로로 넣은 후 페이지에서 경로를 수정해주어야 한다.

list.jsp 파일에서 CSS나 JS 파일 경로를 '/resources로 시작하도록 수정한다.

 

11.1.2 includes 적용

JSP 를 작성할 때마다 많은 양의 HTML 코드를 이용하는 것을 피하기 위해 JSP의 include 지시자를 활용해서 페이지 제작 시에 필요한 내용만을 작성할 수 있게 사전에 작업을 한다.

 

11.1.3 jQuery 라이브러리 변경

JSP 페이지를 작성하다 보면 JavaScript로 브라우저 내에서의 조작이 필요한 경우가 많다.

jQuery를 header.jsp 에 선언해 두면 작성하는 JSP에서 자유롭게 사용할 수 있으므로 수정한다.

 

반응형 웹 처리

SB Admin2는 반응형으로 설계되어 있어서 브라우저의 크기에 맞게 모바일 용으로 자동으로 변경되지만 jQuery의 최신 버전을 사용한 상태에서는 모바일 크기에서 ' 새로고침' 시 메뉴가 펼쳐지는 문제가 발생한다.

이 문제를 해결하기 위해 footer.jsp에 아래와 같은 코드를 기존 코드 대신 추가했다.

 

footer.jsp의 일부
<script>
    $(document).ready(function() {
        $('#dataTables-example').DataTable({
            responsive : true
        });
        $(".sidebar-nav")
        .attr("class","sidebar-nav navbar-collapse collapse")
        .attr("aria-expanded"'false')
        .attr("style","height:1px");/
    });
</script>
cs

 

 


11.2 목록 화면 처리

list.jsp에 JSTL의 출력과 포맷을 적용할 수 있는 태그 라이브러리를 추가한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
 
 
<%@include file="../includes/header.jsp" %>
            <div class="row">
                <div class="col-lg-12">
                    <h1 class="page-header">Tables</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 List Page
                        </div>
                        <!-- /.panel-heading -->
                        <div class="panel-body">
                            <table  class="table table-striped table-bordered table-hover">
                                <thead>
                            <tr>
                                <th>#번호</th>
                                <th>제목</th>
                                <th>작성자</th>
                                <th>작성일</th>
                                <th>수정일</th>
                            </tr>
                        </thead>
                     
                    </table>
                          </div>
                        <!-- /.panel-body -->
                    </div>
                    <!-- /.panel -->
                </div>
                <!-- /.col-lg-6 -->
            </div>
            <!-- /.row -->
        <%@include file="../includes/footer.jsp" %>
 
    
 
cs

 

11.2.1 Model에 담긴 데이터 출력

/boar/list를 실행했을 때 이미 BoardController는 Model 을 이용해서 게시물의 목록을 list라는 이름으로 담아서 전달했으므로 list.jsp 에서는 이를 출력한다. 출력은 JSTL을 이용해서 처리한다.

 

<table  class="table table-striped table-bordered table-hover">
                                <thead>
                            <tr>
                                <th>#번호</th>
                                <th>제목</th>
                                <th>작성자</th>
                                <th>작성일</th>
                                <th>수정일</th>
                            </tr>
                        </thead>
                        
                        <c:forEach items="${list}" var="board">
                            <tr>
                                <td><c:out value="${board.bno }" /></td>
                                <td><c:out value="${board.title }" /></td>
                                <td><c:out value="${board.writer }" /></td>
                                <td><fmt:formatDate value="${board.regdate }" pattern="yyyy-MM-dd"/></td>
                                <td><fmt:formatDate value="${board.updateDate }" pattern="yyyy-MM-dd"/></td>
                            </tr>
                        </c:forEach>
                    </table>
cs

 

브라우저를 통한 결과

 


11.3 등록 입력 페이지와 등록 처리

게시물의 등록 작업POST 방식으로 처리하지만, 화면에서 입력을 받아야 하므로 GET 방식으로 입력 페이지를 볼 수 있도록 BoardController에 메서드를 추가한다.

 

BoardController register 메서드
@GetMapping("/register")
    public void register() {
        
    }
cs

register()는 입력 페이지를 보여주는 역할만을 하기 때문에 별도의 처리가 필요하지 않다.

 

views/board/register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@include file="../includes/header.jsp"%>
 
 
    <div class="row">
        <div class="col-lg-12">
            <h1 class="page-header">Board Register</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 Register</div>
                <!-- /.panel-heading -->
                <div class="panel-body">
 
                    <form role="form" action="/board/register" method="post">
                        <div class="form-group">
                            <label>Title</label> <input class="form-control" name='title'>
                        </div>
 
                        <div class="form-group">
                            <label>Text area</label>
                            <textarea class="form-control" rows="3" name='content'></textarea>
                        </div>
 
                        <div class="form-group">
                            <label>Writer</label> <input class="form-control" name='writer'>
                        </div>
                        <button type="submit" class="btn btn-default">Submit Button</button>
                        <button type="reset" class="btn btn-default">Reset Button</button>
                    </form>
 
                </div>
                <!--  end panel-body -->
 
            </div>
            <!--  end panel-body -->
        </div>
        <!-- end panel -->
    </div>
    <!-- /.row -->
    <%@include file="../includes/footer.jsp"%>
 
cs

register.jsp 페이지에서는 <form> 태그를 이용해서 필요한 데이터를 전송한다.

<input>이나 <textarea> 태그의 name 속성BoardVO 클래스의 변수와 일치시켜 준다.

 

입력 항목을 넣으면 새로운 게시물이 등록된다.

BoardControllerPOST 방식으로 동작하는 register()는 redirect 시키는 방식을 이용하므로, 

게시물의 등록 후에는 다시 /board/list로 이동하게 된다.

 

게시물의 등록은 정상적으로 이루어지지만 한글이 깨지는 문제가 발생한다.

 

 

 

11.3.1 한글 문제와 UTF-8 필터 처리

새로운 게시물을 등록했을 때 한글 입력에 문제가 있다는 것을 발견했다면

1) 브라우저에서 한글이 깨져서 전송되는지를 확인하고, 2) 문제가 없다면 스프링 MVC 쪽에서 한글을 처리하는 필터를 등록해야 한다.

 

위 화면을 보면 브라우저가 한글을 문제없이 보냈음을 알 수 있는데, 문제는 Controller 혹은 데이터베이스 쪽이라는 것을 알 수 있다.

위의 로그를 살펴보면 BoardController에 전달될 때 이미 한글이 깨진 상태로 처리된다.

이 문제를 해결하기 위해서 web.xml에 아래와 같이 필터를 추가한다.

<filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
 
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <servlet-name>appServlet</servlet-name>
    </filter-mapping>
cs

 

 

한글에 대한 처리가 끝난 후 다시 게시물을 작성해 보면 한글에 문제가 없이 입력된다.

 

 

11.3.2 재전송(redirect) 처리

등록 과정에서 POST 방식으로 데이터가 처리되는 과정을 그림으로 표현하면 다음과 같다.

 

 

BoardController에서 register( ) 메서드는 'redirect:/board/list' 를 전송하는데 브라우저는 이를 통보받은 후 '/board/list로 이동하게 된다.

만일 위와 같이 재전송을 하지 않는다면 사용자는 브라우저의 '새로 고침' 을 통해서 동일한 내용을 계속 등록할 수 있기 때문에 문제가 발생하게 된다.

따라서 등록, 수정, 삭제 작업은 처리가 완료된 후 다시 동일한 내용을 전송할 수 없도록 아예 브라우저의 URL을 이동하는 방식을 이용한다.

이러한 과정에서 하나 더 신경 써야하는 것은 브라우저에 등록, 수정, 삭제의 결과를 바로 알 수 있게 피드백을 줘야 한든 점이다. 경고창이나 <div> 를 이용하는 모달창을 이용해서 이러한 작업을 처리할 수 있다.

 

BoardController에서 redirect 처리를 할 때 RedirectAttributes 라는 특별한 타입의 객체를 이용했다.

addFlashAttribute()의 경우 이러한 처리에 적합한데, 그 이유는 일회성으로만 데이터를 전달하기 때문이다.

addFlashAttribute()로 보관된 데이터는 단 한번만 사용할 수 있게 보관된다.(내부적으로는 HttpSession을 이용해서 처리)

 

views/board/list.jsp의 일부
<script type ="text/javascript">
$(document).ready(function(){
            
var result = '<c:out value = "${result}"/>';
                
});
</script>       
cs

 

 

11.3.3 모달(Modal)창 보여주기

최근에는 브라우저에서 경고창(alert)을 띄우는 방식보다 모달창(Modal)을 보여주는 방식을 많이 사용한다.

BootStrap은 모달창을 간단하게 사용할 수 있으므로 목록 화면에서 필요한 메시지를 보여주는 방법을 사용해 보자.

모달창은 기본적으로 <div>를 화면에 특정 위치에 보여주고, 배경이 되는 <div>에 배경색을 입혀서 처리한다.

모달창은 활성화된 <div>를 선택하지 않고는 다시 원래의 화면을 볼 수 없도록 막기 때문에 메시지를 보여주는데 효과적인 방식이다.

모달창에 대한 코드는 SBAdmin2의 pages 폴더 내 notifications.html 파일을 참고하면 된다.

모달창을 처리하기 위해서는 우선 <div>를 이용해서 페이지의 코드에 추가해야 한다.

 

<!-- Modal 추가 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
    aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"
                    aria-hidden="true">&times;</button>
                <h4 class="modal-title" id="myModalLabel">Modal title</h4>
            </div>
            <div class="modal-body">처리가 완료되었습니다.</div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
        <!-- /.modal-content -->
    </div>
    <!-- /.modal-dialog -->
</div>
<!-- /.modal -->
cs

 

모달창을 보여주는 작업은 jQuery를 이용해서 처리할 수 있다.

 

<script type="text/javascript">
            $(document).ready(function(){
                var result = '<c:out value="${result}"/>';
            })
            checkModal(result);
            
            function checkModal(result){
                
                if(result === ''{
                    return;
                }
                
                if (parseInt(result) >0){
                    $(".modal-body").html("게시글" + parseInt(result) + " 번이 등록되었습니다.");
                }
                
                $("#myModal").modal("show");
            }
            });
            </script>
cs

 

checkModal( ) 함수는 파라미터에 따라서 모달창을 보여주거나 내용을 수정한 뒤 보이도록 작성한다.

checkModal( )에서는 새로운 게시글이 작성되는 경우 Redirect Attributes로 게시물의 번호가 전송되므로 이를 이용해서 모달창의 내용을 수정한다.

$("#modal").modal('show')를 호출하면 이의 화면처럼 모달창이 보이게 된다.

 

 

11.3.4 목록에서 버튼으로 이동하기

게시물의 작성과 목록 페이지로 이동이 정상적으로 동작했다면, 마지막으로 목록 페이지 상단에 버튼을 추가해서 등록 작업을 시작할 수 있게 처리하는 것이다.

<div class="panel-heading">Board List Page
<button id='regBtn' type ="button" class="btn btn-xs pull-right">Register
New Board</button>
</div>
cs

 

             <script type="text/javascript">
                $(document).ready(function(){
                    var result = '<c:out value="${result}"/>';
                    checkModal(result);
            
                    function checkModal(result){
                
                        if(result === ''){
                            return;
                        }
                
                            if (parseInt(result) >0){
                            console.log("들어옴?");
                            $(".modal-body").html("게시글" + parseInt(result) + " 번이 등록되었습니다.");
                        }
                
                        $("#myModal").modal("show");
                    }
                    
                    $("#regBtn").on("click"function(){
                        self.location = "/board/register";
                    });
                });
            </script>
cs

 

화면에서 'Register New Board' 버튼을 클릭하면 게시물의 등록 페이지로 이동할 수 있다.

 


11.4 조회 페이지와 이동

게시물의 등록과 리스트 처리가 끝났다면 가장 중요한 틀은 완성되었다고 볼 수 있다.

다음으로는 목록 페이지에서 링크를 통해서 GET 방식으로 특정한 번호의 게시물을 조회할 수 있는 기능을 작성한다.

 

 

11.4.1 조회 페이지 작성

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

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

 

get.jsp는 게시물 번호를 보여줄 수 있는 필드를 추가하고, 모든 데이터는 readonly를 지정해서 작성한다.

register.jsp에 있던 <form> 태그는 조회 페이지에서는 그다지 필요하지 않으므로 제거하는 대신 마지막에는 수정/ 삭제 페이지로 이동하거나 원래의 목록 페이지로 이동할 수 있는 버튼을 추가한다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@include file="../includes/header.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 class = "form-control" rows ="3" 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 data-oper='list' class ="btn btn-info">List</button>
                    
 
                </div>
                <!--  end panel-body -->
 
            </div>
            <!--  end panel-body -->
        </div>
        <!-- end panel -->
    </div>
    <!-- /.row -->
    <%@include file="../includes/footer.jsp"%>
 
cs

 

브라우저에서는 /board/get?bno=1'과 같이 게시물의 번호를 반드시 파라미터로 전달해야 한다.

파라미터로 전달하는 bno 값이 존재한다면 아래와 같은 페이지를 보여준다.

 

 

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

목록 페이지에서 각 게시물 제목에 <a> 태그를 적용해서 조회 페이지로 이동하게 처리한다.

 

 

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

<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 value="${board.regdate }"
pattern="yyyy-MM-dd" /></td>
<td><fmt:formatDate value="${board.updateDate }"
pattern="yyyy-MM-dd" /></td>
</tr>
cs

 

브라우저를 통해 화면을 확인해 보면 각 게시물의 제목에 링크가 걸리는 것을 확인할 수 있고,

제목을 클릭하면 정상적으로 조회 페이지로 이동하는 것을 볼 수 있다.

 

 

뒤로 가기의 문제

동일한 페이지 내에서 목록 페이지와 조회 페이지의 이동은 정상적으로 처리된 것 같아 보이지만 한 가지 문제가 남아 있다.

등록 -> 목록 -> 조회 까지는 순조롭지만 브라우저의 뒤로 가기를 선택하는 순간 다시 게시물의 등록 결과를 확인하는 방식으로 동작한다는 것이다.

 

이러한 문제가 생기는 원인은 브라우저에서 '뒤로 가기'나 '앞으로 가기'를 하면 서버를 다시 호출하는 게 아니라 과거에 자신이 가진 모든 데이터를 활용하기 때문이다.

브라우저에서 조회 페이지와 목록 페이지를 여러 번 앞으로 혹은 뒤로 이동해도 서버에서는 처음에 호출을 제외하고 별다른 변화가 없다는 것을 확인할 수 있다.

 

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

 

<script type="text/javascript">
 $(document).ready(function(){
 var result = '<c:out value="${result}"/>';
checkModal(result);
            
history.replaceState({},nullnull);
                    
function checkModal(result){
                
if(result === '' || history.state ){
   return;
 }
                
 if (parseInt(result) >0){
    console.log("들어옴?");
  $(".modal-body").html("게시글" + parseInt(result) + " 번이 등록되었습니다.");
       }
                
   $("#myModal").modal("show");
       }
                    
   $("#regBtn").on("click"function(){
     self.location = "/board/register";
      });
      });
 </script>
cs

기존과 달라진 점은 맨 마지막에 추가된 history.replaceState() 부분과 checkModal()에서 history.state를 체크하는 부분이다.

 


11.5 게시물의 수정/삭제 처리

게시물의 수정 작업은 일반적으로 1)조회 페이지에서 직접 처리하는 방식이나 2)별도의 수정/삭제 페이지를 만들어서 해당 페이지에서 수정과 삭제를 처리하는 방식을 많이 사용한다.

최근에는 게시물의 조회 페이지에서 댓글 등에 대한 처리가 많아지면서 수정과 삭제는 별개의 페이지에서 하는 것이 일반적이다.

 

조회 페에지에서는 GET 방식으로 처리되는 URL을 통해서 수정/삭제 버튼이 존재하는 화면을 볼 수 있게 제작해야 한다.

수정 혹은 삭제 작업은 POST 방식으로 처리되고, 결과는 다시 목록 화면에서 확인할 수 있는 형태로 제작한다.

 

 

11. 5. 1 수정/삭제 페이지로 이동

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));
    }
cs

 

@GetMapping 이나 @ PostMapping 등에는 URL을 배열로 처리할 수 있으므로, 위와 같이 하나의 메서드로 여러 URL을 처리할 수 있다.

 

브라우저에서는 '/board/modify?bno=30'과 같은 방식으로 처리하므로, views 폴더 내 modify.jsp를 작성한다.

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

POST 방식으로 처리하는 부분을 위해서는 <form> 태그로 내용들을 감싸게 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@include file="../includes/header.jsp"%>
<div class="row">
    <div class="col-lg-12">
        <h1 class="page-header">Board Register</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 Register</div>
            <!-- /.panel-heading -->
            <div class="panel-body">
                <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 class="form-control" rows="3" 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">
                        <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">
                        <label>Writer</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-dafult">Modify</button>
                    <button type="submit" data-oper='remove' class="btn btn-danger">Remove</button>
                    <button type="submit" data-oper='list' class="btn btn-info">List</button>
                </form>
 
            </div>
            <!-- /.panel-body -->
        </div>
        <!-- /.panel -->
    </div>
    <!-- /.col-lg-12 -->
</div>
 
<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>
 
 
<%@include file="../includes/footer.jsp"%>
cs

 

<form> 태그는 action 속성을 '/board/modify'로 지정했지만, 삭제를 하면 '/board/remove'와 같이 action 속성의 내용을 수정해서 사용하게 된다.

게시물의 제목, 내용은 수정이 가능한 형태로 사용해서 사용자가 편집할 수 있게 한다.

등록일과 수정일은 나중에 BoardVO로 수집되어야 하므로 날짜 포맷을 'yyyy/mm/dd'의 포맷으로 해야한다.

 

JavaScript에서는 <button> 태그의 'data-oper' 속성을 이용해서 원하는 기능을 동작하도록 처리한다.

<form>태그의 모든 버튼은 기본적으로 submit으로 처리하기 때문에 e.preventDefault()로 기본 동작을 막고 마지막에 직접 submit()을 수행한다.

 

11.5.2 게시물 수정/삭제 확인

화면에서 게시물을 수정한 후에 'modify' 버튼을 통해서 BoardController에 수정을 요청한다.

 

Modify 버튼을 클릭하면 BoardController에서는 주어진 파라미터들을 BoardVO로 처리하게 되고, 수정된 값이 제대로 수집된 것을 확인할 수 있다.

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

 

화면에서 Remove 버튼을 클릭하게 되면 <form> 태그의 action 값이 '/board/remove'가 되고 데이터들이 전송된다.

 

 

11.5.3 조회 페이지에서 <form> 처리

게시물의 조회 페이지에서는 수정과 삭제가 필요한 페이지로 링크를 처리해야 한다.

직접 버튼에 링크를 처리하는 방식을 사용하여 처리하였지만, 나중에 다양한 상황을 처리하기 위해서 <form> 태그를 이용하여 수정해 보겠다.

<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>
cs

 

브라우저에서는 <form> 태그의 내용은 보이지 않고 버튼만이 보이게 된다.

 

사용자가 버튼을 클릭하면 openForm 이라는 id를 가진 <form> 태그를 전송해야 하므로 추가적인 JavaScript 처리가 필요하다.

 

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

사용자가 수정 버튼을 누르는 경우에는 bno 값을 같이 전달하고 <form> 태그를 submit 시켜서 처리한다.

만일 사용자가 list로 이동하는 경우에는 아직 아무런 데이터도 필요하지 않으므로 <form> 태그 내의 bno 태그를 지우고 submit을 통해서 리스트 페이지로 이동한다.

 

 

11.5.4 수정 페이지에서 링크 처리

수정 페이지에서는 사용자가 다시 목록 페이지로 이동할 수 있도록 하기 위해서 JavaScript의 내용을 조금 수정한다.

<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>
cs

 

수정된 내용은 클릭한 버튼이 List인 경우 action 속성과 method 속성을 변경한다.

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

이후에 코드는 실행되지 않도록 return 을 통해서 제어한다.

 

 


출처 : 코드로 배우는 스프링 웹 프로젝트 [구멍가게 코딩단]

Comments