jQuery AJAX 실습

[JavaScript] jQuery AJAX 실습 코드
Feb 22, 2024
jQuery AJAX 실습

Git Clone

notion image

참고 사이트

게시글 목록보기, 수정화면 이동

index 수정

{{> layout/header}} <div class="container p-5"> <table class="table table-striped"> <thead> <tr> <th>번호</th> <th>제목</th> <th>내용</th> <th>작성자</th> <th></th> </tr> </thead> <tbody> </tbody> </table> </div> <script> function getBoard(){ return` <tr id="board-5"> <td>5</td> <td>제목5</td> <td>내용5</td> <td>홍길동</td> <td> <div class="d-flex"> <form action="#"> <button class="btn btn-danger">삭제</button> </form> <form action="/board/1/updateForm" method="get"> <button class="btn btn-warning">수정</button> </form> </div> </td> </tr> `; } </script> {{> layout/footer}}

BoardApiController 생성

api에 주소에는 보통 복수형을 쓴다.
notion image
@RequiredArgsConstructor @RestController public class BoardApiController { private final BoardRepository boardRepository; @GetMapping("/api/boards") public void findAll(){ List<Board> boardList = boardRepository.selectAll(); } }

ApiUtil 생성

  • Api에서 Header에 상태코드가 있지만 Body에도 상태코드를 담아서 보내줘야 한다.
    • Body를 파싱해서 Client에게 error message를 보내줘야 하기 때문
    • Header의 상태코드에 상관없이 Body를 파싱한다.
@Data public class ApiUtil<T> { private Integer status; // 200, 400, 404, 405 private String msg; // 성공, 실패 시 -> 정확한 메시지 private T body; public ApiUtil(T body) { this.status = 200; this.msg = "성공"; this.body = body; } public ApiUtil(Integer status, String msg) { this.status = status; this.msg = msg; this.body = null; } }

BoardApiController 수정

@RequiredArgsConstructor @RestController public class BoardApiController { private final BoardRepository boardRepository; @GetMapping("/api/boards") public ApiUtil<?> findAll() { List<Board> boardList = boardRepository.selectAll(); return new ApiUtil<>(boardList); } }

실행 해보기

notion image
MessageConverter가 발동하여 JSON으로 바뀌는 것을 확인

jQuery, FontAwesome 추가

header.mustache head에 추가

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">

jQuery 코드 작성

notion image

index.mustache

$.ajax({ url: "/api/boards", type: "get" }).done((res) => { console.log("통신 성공"); console.log(res); }).fail((res) => { console.log("통신 실패") // console.log(res); alert(res.responseJSON.msg); // location.href = "/loginForm"; });
notion image

getboard → render 함수 수정

notion image
한줄이 board
notion image
notion image
function render(board) { return ` <tr id="board-${board.id}"> <td>${board.id}</td> <td>${board.title}</td> <td>${board.content}</td> <td>${board.author}</td> <td> <div class="d-flex"> <button onclick="del(${board.id})" class="btn btn-danger">삭제</button> <form action="/board/${board.id}/updateForm" method="get"> <button class="btn btn-warning">수정</button> </form> </div> </td> </tr> `; }
notion image
notion image
let boardList = res.body; boardList.forEach((board)=>{ $("#board-box").append(render(board)); });

게시글 삭제

BoardApiController

notion image
@DeleteMapping("/api/boards/{id}") public ApiUtil<?> deleteById(@PathVariable Integer id){ boardRepository.deleteById(id); return new ApiUtil<>(null); }

BoardRepository - deleteById 만들기

notion image
@Transactional public void deleteById(Integer id) { Query query = em.createNativeQuery("delete from board_tb where id = ?"); query.setParameter(1, id); query.executeUpdate(); }

ajax 코드 작성

notion image
function del(boardId) { $.ajax({ url: `api/boards/${boardId}`, type: "delete" }).done((res) => { $(`#board-${boardId}`).remove(); }).fail((res) => { alert(res.response.JSON.msg); location.reload(); // F5 }); }

BoardApiController 수정

notion image

게시글 쓰기

JSON은 form태그 사용 불가능

saveForm.mustache 수정

notion image
버튼의 type을 button으로 하거나, form태그를 없애준다.
<div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글쓰기 화면입니다</b></div> <div class="card-body"> <form> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button onclick="btnWrite()" type="button" class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div>

btnWrite 함수 작동되는지 확인

notion image
notion image

BoardApiController

notion image

BoardRequest 생성

notion image
public class BoardRequest { @Data public static class WriteDTO{ private String title; private String content; private String author; } }

PostMapping 수정

notion image

insert 수정

notion image

테스트 코드 수정

notion image

POSTMAN으로 요청해보기

notion image
notion image

ajax 작성

notion image
<script> function btnWrite(){ // JavaScript Object let board = { title: $("#title").val(), content: $("#content").val(), author: $("#author").val() }; console.log(board); // JavaScript Object -> JSON으로 바꾸기 // let boardJson = JSON.stringify(board); // console.log(boardJson); $.ajax({ url: "/api/boards", type: "POST" , data: JSON.stringify(board), contentType: "application/json; charset=utf-8" }).done((res)=>{ location.href = "/"; }).fail((res)=>{ alert(res.responseJSON.msg); }); } </script>

게시글 수정

updateForm.mustache 수정

<div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글수정 화면입니다</b></div> <div class="card-body"> <form> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content"></textarea> </div> <button onclick="btnUpdate()" type="button" class="btn btn-primary form-control">글수정완료</button> </form> </div> </div> </div>

btnUpdate() 함수 작동 확인

<script> function btnUpdate(){ alert("클릭되나"); } </script>
notion image

BoardApiController

notion image

BoardRepository update 틀 만들기

notion image

UpdateDTO와 WriteDTO가 같으므로 WriteDTO 이름 변경

notion image
notion image
💡
DTO의 구성이 같더라도 새로운 DTO를 하나 더 만드는 것이 좋다. 변경될 수도 있기 때문에(수정은 제목과 내용만 하는 것으로) → 사용자 관점

update 완성

notion image

BoardApiController

notion image
@PutMapping("/api/boards/{id}") public ApiUtil<?> update(@RequestBody BoardRequest.WriteAndUpdateDTO requestDTO, @PathVariable Integer id){ boardRepository.update(requestDTO, id); return new ApiUtil<>(null); }

postman 요청

notion image
notion image

ajax 코드 수정

<script> function btnUpdate(){ // JavaScript Object let board = { title: $("#title").val(), content: $("#content").val(), author: $("#author").val() }; // console.log(board); // JavaScript Object -> JSON으로 바꾸기 // let boardJson = JSON.stringify(board); // console.log(boardJson); $.ajax({ url: `/api/boards/{{id}}`, type: "PUT" , data: JSON.stringify(board), contentType: "application/json; charset=utf-8" }).done((res)=>{ location.href = "/"; }).fail((res)=>{ alert(res.responseJSON.msg); }); } </script>

BoardApiController update 수정

💡
id를 가져오기 위해 setAttribute 해야함
notion image
@PutMapping("/api/boards/{id}") public ApiUtil<?> update(@RequestBody BoardRequest.WriteAndUpdateDTO requestDTO, @PathVariable Integer id, HttpServletRequest request){ boardRepository.update(requestDTO, id); request.setAttribute("id",id); return new ApiUtil<>(null); }
notion image
@GetMapping("/board/{id}/updateForm") public String updateForm(@PathVariable int id, HttpServletRequest request) { Board board = boardRepository.selectOne(id); request.setAttribute("board",board); return "board/updateForm"; }

UpdateForm 수정

notion image
<div class="container p-5"> <div class="card"> <div class="card-header"><b>익명 글수정 화면입니다</b></div> <div class="card-body"> <form> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter author" id="author" value="{{board.author}}"> </div> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" id="title" value="{{board.author}}"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" id="content">{{board.author}}</textarea> </div> <button onclick="btnUpdate()" type="button" class="btn btn-primary form-control">글수정완료</button> </form> </div> </div> </div>
 
Share article
RSSPowered by inblog