게시글 수정 버튼 추가, 게시글 화면 수정

뚜우웅이·2023년 4월 10일
0

SpringBoot웹

목록 보기
13/23

게시글 수정 버튼 추가

읽기 전용으로 사용할 post.html을 생성해줍니다.

<!doctype html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head th:insert="~{fragments/common :: head('게시판')}">
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">

    <!-- Bootstrap CSS -->
    <link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css"
          integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" rel="stylesheet">
    <link href="starter-template.css" rel="stylesheet" th:href="@{/css/starter-template.css}">
    <title>게시판</title>
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:insert="~{fragments/common :: menu('board')}">
    <a class="navbar-brand" href="#">Spring Boot Tutorial</a>
    <button aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler"
            data-target="#navbarsExampleDefault" data-toggle="collapse" type="button">
        <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarsExampleDefault">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item active">
                <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">게시판</a>
            </li>
        </ul>
    </div>
</nav>

<div class="container">
    <h2>게시판</h2>
    <form th:object="${board}">
        <input type="hidden" th:field="*{id}">
        <div class="form-group">
            <label for="title">제목</label>
            <input type="text" class="form-control"
                   th:classappend="${#fields.hasErrors('title')} ? 'is-invalid'" id="title"
                   th:field="*{title}" readonly>
        </div>
        <div class="form-group">
            <label for="content">내용</label>
            <textarea class="form-control" id="content"
                      th:classappend="${#fields.hasErrors('content')} ? 'is-invalid'"
                      rows="10" th:field="*{content}" readonly></textarea>
        </div>
        <div class="text-right">
            <a class="btn btn-primary" th:href="@{/board/list}">목록으로</a>
            <a class="btn btn-primary" th:if="${board.title != null and (#authorization.expression('hasAuthority(''ROLE_ADMIN'')')
             or (board.user != null and #authentication.name == board.user.username))}"
               th:href="@{/board/form(id=*{id}, title=*{title}, content=*{content})}">수정</a>
            <button th:if="${board.title != null and (#authorization.expression('hasAuthority(''ROLE_ADMIN'')') or (board.user != null and
             #authentication.name == board.user.username))}" type="button" class="btn btn-primary" th:onclick="|deleteBoard(*{id})|">삭제</button>
        </div>
    </form>
</div>

</div>

<footer th:insert="~{fragments/common :: footer}"></footer>
<script>
    function deleteBoard(id) {
        //DELETE /api/boards/{id}
        if(!confirm("게시글을 삭제하시겠습니까?")){
            return;
        }
        $.ajax({
            type: 'DELETE',
            url: '/api/boards/' + id,
            success: function(result) {
                console.log('result', result);
                alert('삭제됐습니다.');
                //삭제 성공시 요청될 url
                location.href = '/board/list';
            }
        });
    }
</script>

</body>
</html>

제목과 내용 입력칸은 readonly를 사용하여 클릭도 할 수 없게 막아줍니다.
수정 버튼도 전에 form.thml에서 사용했던 것과 같이 게시글 작성자와 로그인한 사용자가 일치하거나 ADMIN 권한을 가지고 있는 경우에만 누를 수 있게 권한을 설정해줍니다.

수정을 누를 때

th:href="@{/board/form(id=*{id}, title=*{title}, content=*{content})}"

위 코드를 사용하여 기존 글의 id값, title, content를 가져옵니다.

BoardController.java 수정

post.html로 이동할 수 있게 GetMapping을 추가해줍니다.

@GetMapping("/post")
    public String post(Model model, @RequestParam(required = false) Long id){
        Board board = boardRepository.findById(id).orElse(null);
        model.addAttribute("board", board);
        return "board/post";
    }

이제 list.html에서 게시글을 클릭 했을 경우 form.html이 아닌 post.html로 이동하게 해줍니다.

<tr th:each="board, i : ${boards}" th:onclick="'location.href=\'/board/post?id=' + ${board.id} + '\';'" style="cursor:pointer;">


ADMIN 권한을 가진 사용자 또는 자신의 작성글을 봤을 때 화면


자신의 글이 아닌 다른 사람의 글을 보는 일반 유저 화면

게시글에 작성일, 작성 시간 표시

post.html을 수정해줍니다.

<div class="container">
    <h2>게시판</h2>

    <form th:object="${board}">
        <input type="hidden" th:field="*{id}">
        <div class="form-group">
            <label for="title">제목</label>
            <input type="text" class="form-control"
                   th:classappend="${#fields.hasErrors('title')} ? 'is-invalid'" id="title"
                   th:field="*{title}" readonly>
        </div>
        <div class="form-group">
            <label for="content">내용</label>
            <textarea class="form-control" id="content"
                      th:classappend="${#fields.hasErrors('content')} ? 'is-invalid'"
                      rows="10" th:field="*{content}" readonly></textarea>
        </div>
        <div class="text-right">
            <a class="btn btn-primary" th:href="@{/board/list}">목록으로</a>
            <a class="btn btn-primary" th:if="${board.title != null and (#authorization.expression('hasAuthority(''ROLE_ADMIN'')')
             or (board.user != null and #authentication.name == board.user.username))}"
               th:href="@{/board/form(id=*{id}, title=*{title}, content=*{content})}">수정</a>
            <button th:if="${board.title != null and (#authorization.expression('hasAuthority(''ROLE_ADMIN'')') or (board.user != null and
             #authentication.name == board.user.username))}" type="button" class="btn btn-primary" th:onclick="|deleteBoard(*{id})|">삭제</button>
        </div>
    </form>
</div>
<div style="float: right; padding-right: 50px; padding-top: 50px " >
    <p>작성일: <span th:text="${#temporals.format(board.createdAt, 'yyyy:MM:dd')}"></span></p>
    <p>작성시간: <span th:text="${#temporals.format(board.createdAt, 'HH:mm:ss')}"></span></p>
</div>

새로운 div를 만들어준 뒤 padding을 사용해 여백을 만들어줍니다.

목록으로 버튼을 눌렀을 경우 원래 있었던 페이지로 이동

post.html 목록 버튼 수정

<a class="btn btn-primary" onclick="history.back()">목록으로</a>

JavaScript의 history.back() 메소드는 브라우저의 이전 페이지로 이동하는 역할을 합니다.

profile
공부하는 초보 개발자

0개의 댓글