๋ชฉ์ฐจ

jQuery .ajax() ๐
๋ฏธ๋์ ๋ด๊ฐ ๋ณด๊ธฐ ์ํด ๋จ๊ฒจ๋
jQuery์ ajax ์ฌ์ฉ๋ฒ๋ง ๊ฐ๋จํ ๋จ๊ธฐ๋ ค๊ณ ํ์ผ๋ ์์ ์ฝ๋์ ์๋ ์ฝ๋๋ค๋ ๊ฐ์ด ์ ๋๊ฒ ์ข์ ๋ฏ ์ถ์ด์ ๊ฐ์ด ๋จ๊น
// ์์
$.ajax({
// ํธ์ถ url
url: '/reply/insert',
// ์ ๋ฌ๋ฐฉ์
type: 'post',
// dataType: "json" // ๋ฐ์ดํฐํ์
json์ผ๋ก ํ ๊ฒฝ์ฐ
// ์ ๋ฌํ ๋ฐ์ดํฐ
data: {'boardId': boardId, 'replyContent': replyContent, 'replyWriter': replyWriter},
// ์ฑ๊ณต ์ ์ฝ๋ฐฑ ํจ์, ๋ฐ์ ์คํจ ์ ์ฝ๋ฐฑ๋ ๋ง๋ค์ด๋ ์ข๋ค.
success: function (data) {
getRelyList();
}
// ๋๊ธ ์กฐํ ์์
function getRelyList(){
let boardId = $("#boardId").val();
$.ajax({
url:'/reply/list',
type:'get',
// ๊ฒ์๊ธ์ ๋ํ ๋๊ธ ๋ชฉ๋ก์ด๋ฏ๋ก boardId๋ฅผ ๋๊น
// ์ด๋ ๊ฒ ์กฐํํด์ผ ๋์(SELECT * FROM reply WHERE board_id = #{boardId})
data:{'boardId':boardId},
success:function(data){
// ๋๊ธ ํ์ด์ง๋ค์ด์
์ฒ๋ฆฌ๋ฅผ ์ํ ๋ณ์(์ด์ , ๋ค์ ์กด์ฌ์ฌ๋ถ, ์์~๋๊ฐ)
let prev = data.pageMaker.prev;
let next = data.pageMaker.next;
let startPage = data.pageMaker.startPage;
parseInt(startPage);
let isPrev = startPage - 1;
let endPage = data.pageMaker.endPage;
parseInt(endPage);
let isNext = endPage + 1;
// console.log('prev : ' + prev + '\n' + 'next : ' + next + '\n' + 'startPage : ' + startPage + '\n' + 'endPage : ' + endPage);
// ์๋ฒ์์ ๊ฐ์ ธ์จ ๋๊ธ ๋ฐ์ดํฐ๋ฅผ $.each๋ก ๋ฃจํ ๋๋ ค์ <div id="replyList">์ฌ๊ธฐ์ ๋ฃ์</div>
let replyHtml = "";
$.each(data.replyList,function(key,value){
replyHtml += '<div>';
replyHtml += '<div>' + '๋๊ธ๋ฒํธ:'+ value.replyId+ ' / ์์ฑ์:' + value.replyWriter + ' / ์์ฑ์ผ: ' + value.regDate;
// click ์ด๋ฒคํธ์์ parameter ๋ฃ์ ๋ ""์์ ''๋ฅผ ๋ถ์ฌ์ค์ผ ํจ(์ด๊ฒ ์ฒ์ ํ ๋ ์๊ทผํ ์คํธ๋ ์ค)
replyHtml += '<button onclick="replyUpdateForm('+ value.replyId +',\'' + value.replyContent + '\');">์์ </button>';
replyHtml += '<button onclick="replyDelete(' + value.replyId + ');">์ญ์ </button></div>';
replyHtml += '<div id="replyContentArea"><p>๋ด์ฉ:'+value.replyContent+'</p>';
replyHtml += '</div>';
});
$("#replyList").html(replyHtml);
// ํ์ด์ง๋ค์ด์
ํ์
viewPagination(boardId, prev, next, startPage, endPage, isPrev, isNext);
}});
}
// ํ์ด์ง๋ค์ด์
์ฒ๋ฆฌ(์ด๋ค ์์ผ๋ก ํ๋ ์๋ฆฌ๋ง ์๊ธฐ ์ํ ์์ ๋ผ์ ๊ฐ๋จํ๊ฒ ํจ)
function viewPagination(boardId, prev, next, startPage, endPage, isPrev, isNext) {
// console.log('prev: ' + prev + '\n' + 'next: ' + next + '\n' + 'startPage: ' + startPage + '\n' + 'endPage: ' + endPage + '\n' + 'isPrev: ' + isPrev + '\n' + 'isNext: ' + isNext);
// ํ์ด์ง๋ค์ด์
์์ญ
let replyPagination = "";
// ์ด์ ํ์ด์ง
if (prev == true) {
replyPagination += '<li>';
replyPagination += '<a href="/reply/list?boardId=' + boardId + '&pageNum=' + isPrev +'">' + "Prev" + '</a>';
replyPagination += '</li>';
}
for (let num = startPage; num <= endPage; num++) {
replyPagination += '<li>';
replyPagination += '<a href="/reply/list?boardId=' + boardId + '&pageNum=' + num +'">' + num + '</a>';
replyPagination += '</li>';
}
// ๋ค์ ํ์ด์ง
if (next == true && endPage > 0) {
replyPagination += '<li>';
replyPagination += '<a href="/reply/list?boardId=' + boardId + '&pageNum=' + isNext +'">' + "Next" + '</a>';
replyPagination += '</li>';
}
// ํ์ด์ง๋ค์ด์
์์ญ์ div์ ๋ถ์
$("#reply-pagination").html(replyPagination);
}
// ๋๊ธ ๋ฆฌ์คํธ ์์ญ
<div class="container">
<div id="replyList"></div>
</div>
// ๋๊ธ ํ์ด์ง๋ค์ด์
์์ญ
<div>
<ul id="reply-pagination" class="pagination pagination-sm no-margin pull-right"></ul>
</div>
controller
// boardId์ Criteria๋ฅผ ๋ฐ์์ ๋๊ธ ๋ชฉ๋ก ๋ฐํ
@GetMapping("/reply/list")
@ResponseBody
public Map<String, Object> replyListPaging(@RequestParam("boardId") Long boardId, Criteria cri) {
Map<String, Object> map = new HashMap<>();
List<ReplyVO> replyList = replyService.findReplyListPaging(boardId, cri);
int replyCount = replyService.findCount(boardId);
// ๋๊ธ ๋ชฉ๋ก
map.put("replyList", replyList);
// ํ์ด์ง๋ค์ด์
ํ๋ฉด ์ฒ๋ฆฌ ๋ฐ์ดํฐ
map.put("pageMaker", new PageMaker(replyCount, cri));
return map;
}
service
package paging.study.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import paging.study.domain.Criteria;
import paging.study.domain.vo.ReplyVO;
import paging.study.mapper.ReplyMapper;
import java.util.List;
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional(readOnly = true)
public class ReplyService {
private final ReplyMapper replyMapper;
public List<ReplyVO> findReplyListPaging(Long boardId, Criteria cri) {
return replyMapper.findReplyListPaging(boardId, cri);
}
public int findCount(Long replyId) {
return replyMapper.findCount(replyId);
}
}
mapper
package paging.study.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import paging.study.domain.Criteria;
import paging.study.domain.vo.ReplyVO;
import java.util.List;
@Mapper
public interface ReplyMapper {
List<ReplyVO> findReplyListPaging(@Param("boardId") Long boardId, @Param("cri") Criteria cri);
int findCount(Long boardId);
}
mapper xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="paging.study.mapper.ReplyMapper">
<resultMap id="replydMap" type="paging.study.domain.vo.ReplyVO">
<id column="reply_id" property="replyId"/>
<result column="board_id" property="boardId"/>
<result column="reply_content" property="replyContent"/>
<result column="reply_writer" property="replyWriter"/>
<result column="reg_date" property="regDate"/>
<result column="update_date" property="updateDate"/>
</resultMap>
<select id="findReplyListPaging" parameterType="map" resultMap="replydMap">
SELECT * FROM t_reply
WHERE board_id = #{boardId}
ORDER BY reg_date DESC
limit #{cri.limitStart}, #{cri.amount}
</select>
<select id="findCount" parameterType="Long" resultType="int">
SELECT COUNT(*) FROM t_reply
WHERE board_id = #{boardId}
</select>
</mapper>
ReplyVO
package paging.study.domain.vo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.time.LocalDateTime;
// ๋๊ธ ์ฉ๋
@Getter @Setter
@ToString
@NoArgsConstructor
public class ReplyVO {
private Long replyId;
private Long boardId;
private String replyContent;
private String replyWriter;
private LocalDateTime regDate;
private LocalDateTime updateDate;
public ReplyVO(Long boardId, String replyContent, String replyWriter) {
this.boardId = boardId;
this.replyContent = replyContent;
this.replyWriter = replyWriter;
}
}
Criteria
package paging.study.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter @Setter
@ToString
public class Criteria {
// for paging
private int pageNum; // ํ์ด์ง ๋ฒํธ(ํ์ฌ ํ์ด์ง๊ฐ ๋ช ํ์ด์ง์ธ์ง)
private int amount; // ํ ํ๋ฉด์ ์ถ๋ ฅํ ํ์ด์ง ๊ฐ์
private int limitStart; // ์ฟผ๋ฆฌ์์ (pageNum -1) * amount ์ฌ์ฉํ๊ธฐ ์ํ ๋ณ์
// for search
private String title;
private String name;
// ๊ธฐ๋ณธ ์์ฑ์์์ ๊ฐ์ ๋ก ํ์ด์ง ๋ฒํธ์ ์ถ๋ ฅ ํ์ด์ง ์ ์ธํ
(ํ์ด์ง๋ค์ด์
์ ์ฑ
์ ๋ฐ๋ผ ๋ณ๊ฒฝํ๋ฉด ๋จ)
public Criteria() {
this(1,10);
}
public Criteria(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
}
// ์ฟผ๋ฆฌ์์ limit 1๋ฒ ์งธ parameter๋ก ์ธ ๊ฐ(mybatis์์ ์ด getter ์ด์ฉํด์ ๊ฐ์ )
public int getLimitStart() {
return this.limitStart = (pageNum - 1) * this.amount;
}
}
PageMaker
package paging.study.domain.paging;
import lombok.Getter;
import lombok.ToString;
import paging.study.domain.Criteria;
@Getter @ToString
// ์ค์ ํ์ด์ง๋ค์ด์
ํ๋ฉด ์ฒ๋ฆฌ ๊ณ์ฐ ๋ด๋น(๊ณตํต ๋ชจ๋)
public class PageMaker {
private int startPage; //ํ์ด์ง ํ๋ฉด ํ๋จ์ ์์ ๋ฒํธ(5ํ์ด์ง๋ผ๊ณ ํ๋ฉด [1][2][3][4][5] ์ฌ๊ธฐ์ ์ ์ผ ์ฒซ ๋ฒ ์งธ ์์๋ฒํธ์ธ [1])
private int endPage; //ํ์ด์ง ํ๋ฉด ํ๋จ์ ๋ ๋ฒํธ(5ํ์ด์ง๋ผ๊ณ ํ๋ฉด [1][2][3][4][5] ์ฌ๊ธฐ์ ์ ์ผ ๋ ๋ฒํธ์ธ [5])
private boolean prev, next; // ์ด์ , ๋ค์ ์กด์ฌ ์ฌ๋ถ
private int totalCount; // ์ ์ฒด ๊ฒ์๊ธ ์
private Criteria cri; // ํ๋ก ํธ์์ ์ ๋ฌํ๋ pageNum(ํ์ฌ ํ์ด์ง), amount(์ถ๋ ฅ ํ์ด์ง) ์ ๋ฌ ์ญํ
public PageMaker(int totalCount, Criteria cri) {
this.totalCount = totalCount;
this.cri = cri;
this.endPage = (int)(Math.ceil(cri.getPageNum() / 10.0) * 10);
this.startPage = this.endPage - 9;
// ์ค์ ๋ ๋ฒํธ
int realEnd = (int)(Math.ceil(totalCount * 1.0) / cri.getAmount());
if (realEnd < this.endPage) {
this.endPage = realEnd;
}
this.prev = this.startPage > 1;
this.next = this.endPage < realEnd;
}
}
๋๊ธ table
-- ๋๊ธ
CREATE TABLE t_reply(
reply_id bigint auto_increment,
board_id bigint,
reply_content varchar (30),
reply_writer varchar (30),
reg_date timestamp,
update_date timestamp,
primary key(reply_id)
);
jQeury์์ ajax๋ฅผ ์ด๋ค ์์ผ๋ก ์ฐ๋์ง ์๊ธฐ ์ํ ๊ฐ๋จํ ์์ ์
to ๋ฏธ๋์ ๋ ๊ทธ๋๋ก ๊ฐ์ ธ๋ค ์ฐ์ง ๋ง๊ณ ์์ ํด์ ์ฐ๋๊ฑธ ๊ถ์ฅํจ(์ ์ง๋ณด์๋ ํ์ฅ์ฑ ๋ฑ์ ๊ณ ๋ คํ๊ณ ์ง ์์ค๊ฐ ์๋)

'IT > development' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [JavaScript] submit control(feat. onsubmit) (0) | 2022.11.22 |
|---|---|
| [spring Boot] Request method 'POST' not supported(feat. thymeleaf) (0) | 2022.11.22 |
| [IDE] intellJ IDEA live template ์์ฑ (0) | 2022.11.21 |
| [mybatis] mybatis ์ด์ค foreach insert(feat. ์ด์ค ๊ณ์ธต ๊ฐ์ฒด ์ ์ฅ) (0) | 2022.11.21 |
| [Spring data JPA] ์ด๊ฐ๋จ CRUD (0) | 2022.11.21 |
๋๊ธ