자바 스프링 부트 5일차 b01 CRUD, 유효성 검사

2026. 4. 9. 21:14대우개발원 수업 내용/spring boot, framework

반응형

4일차까지의 정리

list페이지 검색처리까지

 

5일차 해야할것 view register 게시물을 작성하는(등록)페이지 작성

26-04-09
1. 유효성 검사 (Validation) 설정
2. 게시글 등록 기능 (Register - Create)
3. 게시글 상세 조회 기능 (Read - Read)
4. 게시글 수정 기능 (Modify - Update)
5. 게시글 삭제 기능 (Remove - Delete)

오늘 바꾼것

더보기

 

Spring Boot와 Thymeleaf를 활용해서 웹 게시판의 핵심 기능인 CRUD(Create, Read, Update, Delete)와

유효성 검사(Validation) 흐름을 구현

1. 유효성 검사 (Validation) 설정

  • 의존성 추가: build.gradle에 spring-boot-starter-validation을 추가하여 검증 기능을 활성화
  • DTO 조건 설정: BoardDTO의 필드(title, content 등)에 @NotEmpty, @Size 등의 어노테이션을 붙여
    입력값의 필수 여부와 길이를 제한

2. 게시글 등록 기능 (Register - Create)

  • Controller 구현: @GetMapping으로 등록 폼 화면을 보여주고, @PostMapping으로 입력값을 검증(@Valid)한 뒤 DB에 저장하는 로직을 구현했습니다.
  • View 작성 (register.html): * 타임리프 레이아웃(basic.html)을 적용해 공통 UI를 가져왔습니다.
    • 사용자 입력을 받을 <form> 태그를 구성
    • 유효성 검사 실패 시 alert 창을 띄워 사용자에게 어떤 입력이 잘못되었는지 알려주는 JS 코드를 작성
  • 결과 알림 (list.html): 글 등록 성공 후 목록 페이지로 넘어왔을 때,
    새로 등록된 글 번호(bno)와 함께 "게시물 등록이 완료되었습니다"라는 Bootstrap Modal 창이 뜨도록 연동

3. 게시글 상세 조회 기능 (Read - Read)

  • Controller 구현: /read 경로로 들어오는 GET 요청을 받아 특정 글 번호(bno)의 데이터를
    DB에서 꺼내 모델(Model)에 담아 화면으로 전달
  • View 작성 (read.html):
    • 전달받은 게시글 데이터를 readonly 속성을 사용해 읽기 전용으로 화면에 출력
    • List(목록) 및 Modify(수정) 버튼을 만들고, 페이지 이동 시 검색이나 페이징 상태(link)가 유지되도록 파라미터를 연결
  • 목록에서 연결 (list.html): 게시판 목록의 글 제목에 <a> 태그를 걸어 클릭 시 상세 페이지(/read)로 이동하도록 링크 처리

4. 게시글 수정 기능 (Modify - Update)

Controller 구현: * /modify GET 요청을 /read와 함께 묶어서 수정 화면을 띄우도록 설정.

  • /modify POST 요청을 만들어 유효성 검사 후 통과하면 DB를 수정하고,
    완료되면 다시 상세 페이지(/read)로 리다이렉트 하도록 구현
  • View 작성 (modify.html):
    • 작성자, 등록일 등은 readonly로 막고, 제목과 내용만 수정할 수 있는 <form>을 구성
    • JavaScript를 활용해 Modify 버튼 클릭 시 폼 전송, List 버튼 클릭 시 목록으로 돌아가도록

5. 게시글 삭제 기능 (Remove - Delete)

  • Controller 구현: /remove 요청을 받아 서비스 계층을 통해 해당 글 번호의 데이터를 삭제하고,
    삭제가 완료되면 목록 페이지(/list)로 리다이렉트
  • View 이벤트 연결 (modify.html): 화면의 Remove 버튼을 누르면 JavaScript가 작동하여
    폼의 액션을 /board/remove로 변경한 뒤 POST 방식으로 제출(Submit)하여 삭제를 수행

bulid.gradle에 

implementation 'org.springframework.boot:spring-boot-starter-validation'

dependency(의존성) 추가

 

@Notempty

@Future

같은 validation을 사용할 수 있게 하는 것.


BoardDTO에 validation을 추가

더보기
public class BoardDTO {
    private Long bno;
    @NotEmpty
    @Size(min = 3, max = 100)
    private String title;
    @NotEmpty
    private String content;
    private String writer;
    private LocalDateTime regDate;
    private LocalDateTime modDate;
}

 


BoardController.java에 register 추가

입력받은 값을 전송하기 위한 PostMapping의 register도 필요

@GetMapping("/register")는 등록 페이지를 보여주고,
@PostMapping("/register")는 입력값을 검증해 오류가 있으면 다시 등록 페이지로 리다이렉트하고,

성공 시 새 글을 저장한 뒤 목록 페이지로 리다이렉트
즉, 등록 화면 표시 → 유효성 검사 → 저장 및 결과 전달 흐름을 구현한 코드

더보기
@GetMapping("/register")
public void registerGET() {

}

@PostMapping("/register")
public String registerPost(@Valid BoardDTO boardDTO, BindingResult bindingResult,
                         RedirectAttributes redirectAttributes) {
    log.info("board POST register.........");
    if(bindingResult.hasErrors()) {
        redirectAttributes.addFlashAttribute("errors",
                bindingResult.getAllErrors());
        return "redirect:/board/register";
    }
    log.info(boardDTO);
    Long bno = boardService.register(boardDTO);
    redirectAttributes.addFlashAttribute("result", bno);
    return "redirect:/board/list";
}

 


Controller가 반환하는 뷰에 대응하는 화면을 만들기

list.html을 작성할 때 타임리프의 layout 기능을 활용해서 basic.html을 가져오고,

그 안에서 content 구간을 정의해서 실제 게시판 목록을 표시하는 구조로 만듬.

 

즉, basic.html은 공통 레이아웃(헤더, 푸터 등)을 담당하고, list.html은 그 레이아웃을 확장하면서 게시판 리스트를 보여주는 역할

 

templates/board/register.html 만들기

list.html에서 상단 부분을 가져옴

 

<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/basic.html}">

 

register.html 상단에 코드를 추가

 

타임리프 레이아웃을 활용한 뷰 템플릿 조각

  • : basic.html 같은 공통 레이아웃에서 content 영역을 채우는 부분.
    여기서 카드 형태로 "Board Register" 화면을 구성
  • <script layout:fragment="script" th:inline="javascript"> : 레이아웃의 script 영역에 들어갈 자바스크립트를 정의하는 자리. 타임리프의 th:inline="javascript"를 사용하면 서버 데이터를 JS 코드에 안전하게 삽입 가능


즉, 이 파일은 공통 레이아웃을 가져와서 게시판 등록 화면의 본문과 스크립트 영역을 채우는 뷰

register.html

더보기
<head>
    <title>Board Register</title>
</head>
<div layout:fragment="content">
    <div class="row mt-3">
        <div class="col">
            <div class="card">
                <div class="card-header">
                    Board Register
                </div>
                <div class="card-body">
                    
                </div> <!-- end card body -->
            </div> <!-- end card -->
        </div> <!-- end col -->
    </div><!-- end row -->
</div>

<script layout:fragment="script" th:inline="javascript">
    
    
</script>

 

 

이 코드를 다 작성하고 실행하면 아래처럼 화면이 나옴


register.html

내용을 추가하기 위해

form을 추가

 

더보기
<form action="/board/register" method="post">
  <div class="input-group mb-3">
    <span class="input-group-text">Title</span>
    <input type="text" name="title" class="form-control" placeholder="Title">
  </div>

  <div class="input-group mb-3">
    <span class="input-group-text">Content</span>
    <textarea class="form-control col-sm-5" rows="5" name="content"></textarea>
  </div>

  <div class="input-group mb-3">
    <span class="input-group-text">Writer</span>
    <input type="text" name="writer" class="form-control" placeholder="Writer">

  </div>

  <div class="my-4">
    <div class="float-end">
      <button type="submit" class="btn btn-primary">Submit</button>
      <button type="reset" class="btn btn-secondary">Reset</button>
    </div>
  </div>
</form>
 

 

그리고 아래쪽 script 쪽에

아무것도 작성하지 않으면 alert 창이 뜨도록 작성

register.html

 
더보기
<script layout:fragment="script" th:inline="javascript">
const errors = [[${errors}]]
console.log(errors)
let errorMsg = ''
    if (errors) {
        for(let i=0; i<errors.length; i++) {
            errorMsg += `${errors[i].field}은(는) ${errors[i].code} \n`
        }
        alert(errorMsg)
    }
</script>

 실행 해서 아무것도 입력하지 않고 등록버튼을 눌러보면

사진처럼 뜬다.

 

내용을 입력하면 list에 정상적으로 등록됨


list.html

alert창이 뜨도록 아래 코드를 추가

==> 등록한 bno가 몇번인지 뜨도록

더보기
// show moal
    const result = [[${result}]]
    if (result){
       alert(result)
    }
 

 

코드를 추가하면

결과(bno)가 뜸


list.html

위에서 한것을 modal창으로 뜨게 변경

</div><!-- end row-->

코드 아래에

아래 modal 코드 추가

 
더보기
<div class="modal" tabindex="-1">
   <div class="modal-dialog">
      <div class="modal-content">
         <div class="modal-header">
            <h5 class="modal-title">Modal title</h5>
            <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
         </div>
         <div class="modal-body">
            <p>Modal body text goes here.</p>
         </div>
         <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
            <button type="button" class="btn btn-primary">Save changes</button>
         </div>
      </div>
   </div>
</div>

 


list.html

하단 코드를 변경

더보기
// show modal
    const result = [[${result}]]
    // if (result){
    //    alert(result)
    // }
    const modal = new bootstrap.Moal(document.querySelector(".modal"))
    if (result){
       modal.show()
    }

 

실행하면 modal창이 뜸


list.html

modal 창을 수정

더보기
   <div class="modal" tabindex="-1">
      <div class="modal-dialog">
         <div class="modal-content">
            <div class="modal-header">
               <h5 class="modal-title">게시글 등록 확인</h5>
               <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
               <p>게시물 등록이 완료되었습니다.</p>
            </div>
            <div class="modal-footer">
               <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<!--               <button type="button" class="btn btn-primary">Save changes</button>-->
            </div>
         </div>
      </div>
   </div>

result가 있다면 modal창을 띄우라고 해놨기 때문에

register에서 list로 넘어갈때만 modal창이 뜸

1. modal-title에 게시글 등록확인으로 변경

2. modal-body 게시글 등록이 완료되었습니다.로 변경

3. Save 버튼 없앰

실행하면


read

 

1. BoardController에 read 항목을 추가

더보기
@GetMapping("/read")
public void read(Long bno, PageRequestDTO pageRequestDTO, Model model) {
    BoardDTO boardDTO = boardService.readOne(bno);
    log.info(boardDTO);
    model.addAttribute("dto", boardDTO);
}

2. read.html 생성

 

상단에 네임테그스페이스 추가

타임리프(Thymeleaf)와 Ultraq Layout Dialect를 활용한 뷰 템플릿

  • 상단의 xmlns:th와 xmlns:layout 네임스페이스 선언은 타임리프와 레이아웃 기능을 사용하기 위해 필요
  • layout:decorate="~{layout/basic.html}"는 basic.html을 기본 레이아웃으로 가져와서
    이 페이지(read.html)의 구조를 그 레이아웃에 맞춰 확장
  • <script layout:fragment="script" th:inline="javascript">는 basic.html에서 정의된 content 영역을 채우는 부분으로,
    여기서는 "Board Read" 화면을 카드 형태로 구성

 

더보기
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/basic.html}">

<head>
    <title>Board Read</title>
</head>

<div layout:fragment="content">
    <div class="row mt-3">
        <div class="col">
            <div class="card">
                <div class="card-header">
                    Board Read
                </div>
                <div class="card-body">



                </div><!--end card body-->



            </div><!--end card-->
        </div><!-- end col-->
    </div><!-- end row-->
</div>


<script layout:fragment="script" th:inline="javascript">



</script>

 이제 실행하면 아래 사진처럼 나옴

(아직 링크처리는 안했기 때문에 직접 경로를 지정해서 실행.)

아직 내용 DB를 안불러 왔기 때문에 안뜨는게 맞음


<div class="card-body">

card-body 아래에(안에)

태그를 추가해서 내용이 보이도록

아래의 코드를 추가

 

- 각 <div class="input-group mb-3"> 블록은 글의 속성(Bno, Title, Content, Writer, RegDate, ModDate)을 보여주는 
입력 필드나 텍스트 영역
- th:value="${dto.title}", [[${dto.content}]] 같은 표현식은 컨트롤러에서 전달한 BoardDTO 객체의 값을 화면에 출력
- 모든 필드에 readonly 속성을 줘서 수정은 못 하고 조회 전용으로 표시
- 마지막 버튼 영역(List, Modify)은 목록 화면으로 돌아가거나 수정 화면으로 이동할 수 있도록 UI를 제공

즉, 컨트롤러에서 넘겨준 게시글 데이터를 읽기 전용으로 보여주는 뷰 코드

더보기
<div class="input-group mb-3">
    <span class="input-group-text">Bno</span>
    <input type="text" class="form-control" th:value="${dto.bno}" readonly>
</div>
<div class="input-group mb-3">
    <span class="input-group-text">Title</span>
    <input type="text" class="form-control" th:value="${dto.title}" readonly>
</div>

<div class="input-group mb-3">
    <span class="input-group-text">Content</span>
    <textarea class="form-control col-sm-5" rows="5" readonly>[[${dto.content}]]</textarea>
</div>

<div class="input-group mb-3">
    <span class="input-group-text">Writer</span>
    <input type="text" class="form-control" th:value="${dto.writer}" readonly>
</div>

<div class="input-group mb-3">
    <span class="input-group-text">RegDate</span>
    <input type="text" class="form-control" th:value="${#temporals.format(dto.regDate, 'yyyy-MM-dd HH:mm:ss')}" readonly>
</div>
<div class="input-group mb-3">
    <span class="input-group-text">ModDate</span>
    <input type="text" class="form-control" th:value="${#temporals.format(dto.modDate, 'yyyy-MM-dd HH:mm:ss')}" readonly>
</div>

<div class="my-4">
    <div class="float-end" >
        <button type="button" class="btn btn-primary">List</button>
        <button type="button" class="btn btn-secondary">Modify</button>
        </a>
    </div>
</div>

 

이 코드를 추가 한다음에 실행하면

내용이 정상적으로 뜸


List, Modify에 연결될 수있게 하는 링크를 연결하는 코드 추가

 

th:with="link = ${pageRequestDTO.getLink()}"

 : 컨트롤러에서 전달된 `pageRequestDTO`의 링크 정보를 지역 변수 `link`로 저장

th:href="|@{/board/list}?${link}|"

: 목록 버튼을 누르면 `board/list`로 이동하면서 페이지 요청 파라미터(`link`)를 붙여줌

th:href="|@{/board/modify(bno=${dto.bno})}&${link}|"

:수정 버튼을 누르면 해당 글 번호(`dto.bno`)와 페이지 파라미터를 포함해 `board/modify`로 이동 

즉, 목록으로 돌아갈 때도 페이지 정보가 유지되고, 수정 화면으로 이동할 때도 현재 글 번호와 페이지 정보를 함께 전달하는 구조

read.html  

더보기
<div class="my-4">
    <div class="float-end" th:with="link = ${pageRequestDTO.getLink()}">
        <a th:href="|@{/board/list}?${link}|" class="text-decoration-none">
        <button type="button" class="btn btn-primary">List</button>
            </a>
        <a th:href="|@{/board/modify(bno=${dto.bno})}&${link}|" class="text-decoration-none">
        <button type="button" class="btn btn-secondary">Modify</button>
        </a>
    </div>
</div>

실행 하면

List 버튼을 누르면

Modify는 아직 modify.html이 없어서 눌러도 오류가 뜸


list.html

title을 누르면 read로 연결되도록

코드 추가

 

<tbody th:with="link = ${pageRequestDTO.getLink()}">


: 컨트롤러에서 전달된 pageRequestDTO의 링크 정보를 지역 변수 link로 저장

<tr th:each="dto:${responseDTO.dtoList}">


: responseDTO.dtoList에 담긴 게시글 목록을 하나씩 반복하며 행을 생성

[[${dto.bno}]], [[${dto.title}]], [[${dto.writer}]]


: 각 게시글의 번호, 제목, 작성자를 출력

<a th:href="|@{/board/read(bno = ${dto.bno})}&${link}|">


: 제목을 클릭하면 해당 글 상세 페이지(/board/read)로 이동하며 페이지 정보(link)도 함께 전달

[[${#temporals.format(dto.regDate, 'yyyy-MM-dd')}]]


: 등록일을 yyyy-MM-dd 형식으로 출력

 

list.html

더보기
                  <tbody th:with="link = ${pageRequestDTO.getLink()}">
                  <tr th:each="dto:${responseDTO.dtoList}"  >
                     <th scope="row">[[${dto.bno}]]</th>
                     <td>
<!--                        [[${dto.title}]]-->
                        <a th:href="|@{/board/read(bno = ${dto.bno})}&${link}|"> [[${dto.title}]]</a>
                     </td>
                     <td>[[${dto.writer}]]</td>
<!--                     <td>[[${dto.regDate}]]</td>-->
                     <td>[[${#temporals.format(dto.regDate, 'yyyy-MM-dd')}]]</td>
                  </tr>
                  </tbody>

실행하면 링크가 정상적으로 연결되서 list에서 title을 클릭하면 read로 연결된다.


modify도 가능하도록

1. BoardController 수정

BoardController

더보기
//    @GetMapping("/read")
    @GetMapping({"/read", "/modify"})
    public void read(Long bno, PageRequestDTO pageRequestDTO, Model model) {
        BoardDTO boardDTO = boardService.readOne(bno);
        log.info(boardDTO);
        model.addAttribute("dto", boardDTO);
    }

 


2. modify.html 생성

modify는 수정을 해서 저장까지 해야하기 때문에

form 태그가 필요하다

bno, wirter, regDate, modDate는 readonly를 넣어서 수정이 불가능하게 하고

나머지는 수정이 가능하도록

예)

th:value="${dto.title}

이렇게 적는다

modify.html 

더보기
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/basic.html}">

<head>
    <title>Board Modify</title>
</head>

<div layout:fragment="content">
    <div class="row mt-3">
        <div class="col">
            <div class="card">
                <div class="card-header">
                    Board Modify
                </div>
                <div class="card-body">
                    <form th:action="@{/board/modify}" method="post" id="f1">
                        <div class="input-group mb-3">
                            <span class="input-group-text">Bno</span>
                            <input type="text" class="form-control" th:value="${dto.bno}" name="bno" readonly>
                        </div>
                        <div class="input-group mb-3">
                            <span class="input-group-text">Title</span>
                            <input type="text" class="form-control" name="title" th:value="${dto.title}">
                        </div>

                        <div class="input-group mb-3">
                            <span class="input-group-text">Content</span>
                            <textarea class="form-control col-sm-5" rows="5" name="content">[[${dto.content}]]</textarea>
                        </div>

                        <div class="input-group mb-3">
                            <span class="input-group-text">Writer</span>
                            <input type="text" class="form-control" th:value="${dto.writer}" name="writer" readonly>
                        </div>

                        <div class="input-group mb-3">
                            <span class="input-group-text">RegDate</span>
                            <input type="text" class="form-control" th:value="${#temporals.format(dto.regDate, 'yyyy-MM-dd HH:mm:ss')}" readonly>
                        </div>
                        <div class="input-group mb-3">
                            <span class="input-group-text">ModDate</span>
                            <input type="text" class="form-control" th:value="${#temporals.format(dto.modDate, 'yyyy-MM-dd HH:mm:ss')}" readonly>
                        </div>

                        <div class="my-4">
                            <div class="float-end">
                                <button type="button" class="btn btn-primary listBtn">List</button>
                                <button type="button" class="btn btn-secondary modBtn">Modify</button>
                                <button type="button" class="btn btn-danger removeBtn">Remove</button>
                            </div>
                        </div>
                    </form>


                </div><!--end card body-->
            </div><!--end card-->
        </div><!-- end col-->
    </div><!-- end row-->
</div>

<script layout:fragment="script" th:inline="javascript">


    const errors = [[${errors}]]
    console.log(errors)

    let errorMsg = ''

    if(errors){
        for (let i = 0; i < errors.length; i++) {
            errorMsg += `${errors[i].field}은(는) ${errors[i].code} \n`
        }
        history.replaceState({}, null, null)
        alert(errorMsg)
    }

    const link = [[${pageRequestDTO.getLink()}]]
    const formObj = document.querySelector("#f1")

    document.querySelector(".modBtn").addEventListener("click", function(e){
        e.preventDefault()
        e.stopPropagation()

        formObj.action = `/board/modify?${link}`
        formObj.method ='post'
        formObj.submit()


    }, false)


    document.querySelector(".removeBtn").addEventListener("click", function(e){
        e.preventDefault()
        e.stopPropagation()

        formObj.action = `/board/remove`
        formObj.method ='post'
        formObj.submit()
    }, false)

    document.querySelector(".listBtn").addEventListener("click", function(e){
        e.preventDefault()
        e.stopPropagation()

        formObj.reset()
        self.location =`/board/list?${link}`

    }, false)


</script>

 

코드를 넣고

실행하면

title과 content만 변경이 가능한것을 알 수 있다.

 


이제 Modify 버튼이 동작 하도록

BoardController에 코드 추가

 

 

 

if(bindingResult.hasErrors()) { ... return "redirect:/board/modify?"+link; }


: 유효성 검사에서 오류가 발생하면 에러 메시지를 FlashAttribute로 담고, 수정 화면으로 다시 리다이렉트하며 페이지 정보(link)와 글 번호(bno)를 전달

boardService.modify(boardDTO);


: 오류가 없을 경우 서비스 계층을 호출해 실제 게시글 데이터를 수정

redirectAttributes.addFlashAttribute("result", "modified");


: 수정 성공 메시지를 FlashAttribute로 담아 다음 요청에서 사용할 수 있도록 전달

redirectAttributes.addAttribute("bno", boardDTO.getBno()); return "redirect:/board/read";


: 수정된 글 번호를 파라미터로 넘겨주고, 수정 완료 후 해당 글 상세보기 페이지로 리다이렉트

BoardController.java

더보기
@PostMapping("/modify")
public String modify(@Valid BoardDTO boardDTO,
                     BindingResult bindingResult,
                     PageRequestDTO pageRequestDTO,
                     RedirectAttributes redirectAttributes){
    log.info("board modify post.........." + boardDTO);
    if(bindingResult.hasErrors()) {
        log.info("has errors..........");
        String link = pageRequestDTO. getLink();
        redirectAttributes.addFlashAttribute("errors", bindingResult.getAllErrors());
        redirectAttributes.addAttribute("bno", boardDTO.getBno());
        return "redirect:/board/modify?"+link;
    }
    boardService.modify(boardDTO);
    redirectAttributes.addFlashAttribute("result", "modified");
    redirectAttributes.addAttribute("bno", boardDTO.getBno());
    return "redirect:/board/read";
}

 

 

실행하면 정상적으로 변경된다.


modify버튼은 아래 코드로 인해 동작함


remove

 

1. BoardController에 코드 추가

 boardService.remove(bno);


  : 전달받은 글 번호(`bno`)를 이용해 서비스 계층에서 해당 게시글을 삭제  

redirectAttributes.addFlashAttribute("result", "removed");


  : 삭제 성공 메시지를 FlashAttribute로 담아 다음 요청에서 사용할 수 있도록 전달  

return "redirect:/board/list";


  : 삭제가 완료되면 게시글 목록 페이지로 리다이렉트  

더보기
@GetMapping("remove")
public String remove(Long bno, RedirectAttributes redirectAttributes) {
    log.info("remove post...." + bno);
    boardService.remove(bno);
    redirectAttributes.addFlashAttribute("result", "removed");
    return "redirect:/board/list";
}

 


modify.html

에 이미 list와 remove 버튼에 대한 동작이 추가 되어 있다

삭제 버튼을 누르면 폼을 POST 방식으로 /board/remove에 제출해서 해당 글을 삭제하도록 동작하는 코드

더보기
document.querySelector(".removeBtn").addEventListener("click", function(e){
    e.preventDefault()
    e.stopPropagation()

    formObj.action = `/board/remove`
    formObj.method ='post'
    formObj.submit()
}, false)

목록 버튼을 누르면 폼을 초기화하고, 현재 페이지 정보를 유지한 채 게시판 목록 화면으로 이동하는 코드

더보기
document.querySelector(".listBtn").addEventListener("click", function(e){
    e.preventDefault()
    e.stopPropagation()

    formObj.reset()
    self.location =`/board/list?${link}`

}, false)

 

근데 remove에서 list로 넘어갈때 아까 설정했던 게시글 등록이 완료되었다는 modal이 뜨기 때문에

다른 modal을 추가해서 삭제가 완료되었다는 modal창을 추가하면 좋음