2022. 4. 18. 16:10ㆍ[Spring]_/[Spring]_포트폴리오 페이지 만들기
[환경]
개발툴 : IntelliJ
DB : oracle
프레임워크 : spring , mybatis
----
개발 목표 : 기존에 만든 게시판에서 페이징 처리가 가능하도록 기능 추가
[완료화면]
10개씩 보기
20개씩 보기
이전 조회 기능에서 변경점]
https://yn971106.tistory.com/77?category=1000475
아래의 코드에서
data.forEach(function(value){
console.log(value);
html += '<tr>';
html += '<td>'+value.bno+'</td>';
html += '<td>'+value.title+'</td>';
html += '<td>'+value.writer+'</td>';
html += '<td>'+value.regdate+'</td>';
html += '<td>'+value.viewcnt+'</td>';
html += '</tr>';
});
$('#table').empty()
$('#table').append(html)
fetch 에서 데이터를 받아오면 그값을 html에 담아서 append 하는 방식에서 다음 방식으로 변경
.then(data => {
for (let i = 0; i < data.length; i++) {
let node = document.createElement('tr');
const template = `
<th>\${data[i].bno}</th>
<th>\${data[i].title}</th>
<th>\${data[i].writer}</th>
<th>\${data[i].regdate}</th>
<th>\${data[i].viewcnt}</th>
`
node.innerHTML = template;
tbody.appendChild(node);
}
;
});
가독성이 더 보기 좋아졌습니다.
------
[ 페이징 처리 ]
설계:
1번 : 10개씩, 15개씩, 20개씩 보기를 선택시 그에 맞게 리스트가 변경된다.
2번 : 페이지 번호 클릭시 --개씩 보기의 기능이 적용된 상태에서 선택한 페이지의 게시글이 나오게 한다.
html]
<select id="selectview">
<option value="10" selected="selected">10개씩 보기</option>
<option value="15">15개씩 보기</option>
<option value="20">20개씩 보기</option>
</select>
selected 옵션을 통해 default 값은 10으로 지정하였습니다.
<span id="nav"></span>
테이블 하단에 a 태그인 페이징 넘버 리스트가 올 곳을 만들었습니다.
Script 소스코드]
let regibtn = document.querySelector('.regi');
let tbody = document.querySelector('#table');
let viewcnt = document.querySelector('#selectview');
let nav = document.querySelector('#nav');
regibtn.onclick = function () {
$('#main_content').load("/regi/loader", function () {
});
}
let cnt;
let totalpagecnt;
await counttotal();
createPagenation();
await createBoard(1);
viewcnt.onchange =function(){
createPagenation()
createBoard(1)
}
async function counttotal() {
await fetch('/board/boardcount.do', {
method: "POST",
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({})
}).then(res => res.json())
.then(data => {
cnt = data;
})
}
function createPagenation() {
while(nav.firstChild){
nav.removeChild(nav.firstChild);
}
//총 페이지 수
totalpagecnt = Math.ceil(cnt / viewcnt.value);
//페이지 숫자 생성.
for (let i = 1; i <= totalpagecnt; i++) {
//html 생성하기.
let node = document.createElement('a');
const template = `
<a class="navclick" href="javascript:void(0)">\${i}</a>
`
node.innerHTML = template;
node.querySelector('a').onclick = function () {
createBoard(i);
}
nav.appendChild(node);
}
}
async function createBoard(nowpage) {
while(tbody.firstChild){
tbody.removeChild(tbody.firstChild);
}
await fetch('/board/search.do', {
method: "POST",
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
view: viewcnt.value, // ~만큼 보기
pagenum: nowpage // 페이지 숫자클릭넘버.
})
}).then(res => res.json())
.then(data => {
for (let i = 0; i < data.length; i++) {
let node = document.createElement('tr');
const template = `
<th>\${data[i].bno}</th>
<th>\${data[i].title}</th>
<th>\${data[i].writer}</th>
<th>\${data[i].regdate}</th>
<th>\${data[i].viewcnt}</th>
`
node.innerHTML = template;
tbody.appendChild(node);
}
;
});
}
js 설명]
1. 게시판 총 count를 가져오는 함수.
async function counttotal() {
await fetch('/board/boardcount.do', {
method: "POST",
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({})
}).then(res => res.json())
.then(data => {
cnt = data;
})
}
1-1 ] Controller
@RequestMapping("/board/boardcount.do")
@ResponseBody
public Integer searchcount() throws Exception{
Integer result = boardService.searchcnt();
System.out.println("result = " + result);
return result;
}
Service, ServiceImpl , Mapper 생략
1-2 ] Mapper.xml
<select id="searchcnt" resultType="int">
select count(0) from board
</select>
바라보는 테이블의 총수를 카운트 하여 Int 로 반환합니다.
fetch 통신 이후에는 cnt 라는 변수에 해당 값을 저장합니다.
2. 페이징 함수
function createPagenation() {
while(nav.firstChild){
nav.removeChild(nav.firstChild);
}
//총 페이지 수
totalpagecnt = Math.ceil(cnt / viewcnt.value);
//페이지 숫자 생성.
for (let i = 1; i <= totalpagecnt; i++) {
//html 생성하기.
let node = document.createElement('a');
const template = `
<a class="navclick" href="javascript:void(0)">\${i}</a>
`
node.innerHTML = template;
node.querySelector('a').onclick = function () {
createBoard(i);
}
nav.appendChild(node);
}
}
우선 호출시 자식 노드를 지우고 시작합니다 ( 지우지 않으면 계속 쌓이는 버그발생)
총 페이지 수 = > 게시판의 총 게시물 / 얼만큼 보여줄건지의 값
ex) 54개의 게시물 -> 10개씩 보기 를 선택하면 총 5개의 페이지가 생길 것입니다.
페이지 숫자는 for문을 통해 페이지의 수만큼 반복하고 a 태그를 생성합니다.
생성과 동시에 이벤트를 부착하고 createboard 에 각각의 숫자에 해당하는 값을 파라미터로 전달합니다.
3. 게시판 생성 부분
async function createBoard(nowpage) {
while(tbody.firstChild){
tbody.removeChild(tbody.firstChild);
}
await fetch('/board/search.do', {
method: "POST",
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
view: viewcnt.value, // ~만큼 보기
pagenum: nowpage // 페이지 숫자클릭넘버.
})
}).then(res => res.json())
.then(data => {
for (let i = 0; i < data.length; i++) {
let node = document.createElement('tr');
const template = `
<th>\${data[i].bno}</th>
<th>\${data[i].title}</th>
<th>\${data[i].writer}</th>
<th>\${data[i].regdate}</th>
<th>\${data[i].viewcnt}</th>
`
node.innerHTML = template;
tbody.appendChild(node);
}
;
});
}
파라미터로 지금 바라보고 있는 페이지 를 받습니다.
fetch 통신으로 보여줄 게시판의 수와 지금 바라보고 있는 페이지의 값을 전달합니다.
3-1] Controller
@RequestMapping(value = "/board/search.do")
@ResponseBody
public String boardSearchPOST(@RequestBody Map<String, String> map) throws Exception{
System.out.println(" board 조회시작= ");
Integer viewcnt = Integer.parseInt(map.get("view"));
Integer nowpage = Integer.parseInt(map.get("pagenum"));
Integer start = viewcnt * (nowpage-1) +1;
Integer last = start + viewcnt -1;
System.out.println("start + last = " + start + last);
List list = boardService.boardSearch(start,last);
System.out.println("list = " + list);
System.out.println(" board 조회끝= ");
String json = new Gson().toJson(list);
System.out.println("json = " + json);
return json;
}
게시판 기준으로.
시작할 번호 = 보여줄 게시판 수 * (지금 바라보는 페이지 번호 - 1) + 1
ex ) 10개씩 보여줄 것이며, 지금 페이지 2를 선택했다고 가정시.
10 * (2 -1 ) +1 = 11
즉 시작번호가 11부터라는 의미입니다.
마지막 번호 = 시작할 번호 + 보여줄 게시판 수 - 1
ex ) 10개씩 보여줄 것이며, 지금 페이지 2를 선택했다고 가정 시.
11 + 10 - 1 = 20
즉 시작은 11~ 20 번까지의 게시판을 불러오겠다는 의미입니다.
Service, ServiceImpl , Mapper 생략
3-2.] Mapper.xml
<select id="boardSearch" resultType="com.yoon.model.BoardVO">
select bno,title,writer,regdate,viewcnt
from board
where bno between #{start} AND #{last}
order by regdate desc
</select>
해당 쿼리는
start , last 의 int 값을 받고 게시판 객체를 반환하게 됩니다. 순서는 작성일 기준으로 내림차순입니다.
between을 이용해서 사이의 값만 쿼리로 가져오는 것입니다.
3-3] 받아온 값 처리
for (let i = 0; i < data.length; i++) {
let node = document.createElement('tr');
const template = `
<th>\${data[i].bno}</th>
<th>\${data[i].title}</th>
<th>\${data[i].writer}</th>
<th>\${data[i].regdate}</th>
<th>\${data[i].viewcnt}</th>
`
node.innerHTML = template;
tbody.appendChild(node);
}
;
이를 Json 형식으로 전달하고, script 부분에서는 . 을 통해 key 값으로 접근하여
반복문을 통해 template를 생성합니다.
그리고 이를 tbody에 자식노드로 붙입니다.
'[Spring]_ > [Spring]_포트폴리오 페이지 만들기' 카테고리의 다른 글
[포트폴리오 페이지]_13단계_CRUD 게시판 구현_(신규 데이터 Create) (0) | 2022.04.26 |
---|---|
[포트폴리오 페이지]_12단계_SPA 구현을 위한 History 객체 만들기 (0) | 2022.04.26 |
[포트폴리오 페이지]_8단계_로그인 기능구현_(feat.oracleDB) (0) | 2022.04.03 |
[포트폴리오 페이지]_10단계_CRUD 게시판 구현_(feat.등록기능 구현) (0) | 2022.04.03 |
[포트폴리오 페이지]_9단계_CRUD 게시판 구현_(feat.목록 조회기능 구현) (0) | 2022.04.03 |