- 네이버 지식인 QnA글 목록 화면



카테고리는 애초에 만들 생각이 없었기 때문에 지웠고
당연히 관심질문 등 유저의 정보를 나타내는 공간이 필요 없다고 생각하여 뺏습니다
또한 질문 게시판과 QnA게시판의 차이를 모르겠어서 그냥 QnA게시판만 만들기로 했습니다.
- boardQnA.jsp - script
main화면의 QnA 리스트와 크게 다른점이 없지만
제목으로만 보기 , 내용까지 보기 버튼을 추가했다는 약간의 차이점이 있습니다.
어떻게 만들어야할지 고민하다가 그냥 무식하고 편한 방법으로
2가지 상황의 Container를 2개 만들고,
버튼 클릭에 따라 display를 none / block으로 바뀌게 만들었습니다
<script>
const previewTypeQna = () => {
제목 / 내용 미리보기 List의 display를 변경해주는 함수
const previewTypeQna = document.getElementById('previewTypeQna');
내용까지 보기 display 변경을 위한 document 객체
const titleTypeQna = document.getElementById('titleTypeQna');
제목만 보기 display 변경을 위한 document 객체
const numResult = document.getElementById('numResult');
const ajaxNumResult = document.getElementById('ajax-numResult');
내용까지 보기 상태에서 다음페이지로 넘어가는 경우
인덱스의 qnaList와 마찬가지로 화면의 맨위로 올라가는 상황이였기 떄문에
페이징을 ajax와 일반 페이징으로 2가지 사용하였습니다.
$('#type_title').removeClass('type_title1');
$('#type_preview').removeClass('type_preview1');
$('#type_title').addClass('type_title');
$('#type_preview').addClass('type_preview');
previewTypeQna.style.display = "block";
numResult.style.display = "block";
titleTypeQna.style.display = "none";
ajaxNumResult.style.display = "none";
List를 보고 있는 메뉴의 상태를 생상에 따라 알려주고 있기 떄문에
class이름으로 스타일을 주고 제이쿼리를 사용하여
클릭에 따라 클래스의 이름을 변경 스타일이 변경될 수 있게 만들었습니다
}
const titleTypeQna = () => {
const titleTypeQna = document.getElementById('titleTypeQna');
제목만 보기 display 변경을 위한 document 객체
const previewTypeQna = document.getElementById('previewTypeQna');
내용까지 보기 display 변경을 위한 document 객체
const numResult = document.getElementById('numResult');
const ajaxNumResult = document.getElementById('ajax-numResult');
위의 설명과 마찬가지로 페이징을 보여주는 document 객체
$('#type_title').removeClass('type_title');
$('#type_preview').removeClass('type_preview');
$('#type_title').addClass('type_title1');
$('#type_preview').addClass('type_preview1');
previewTypeQna.style.display = "none";
numResult.style.display = "none";
titleTypeQna.style.display = "block";
ajaxNumResult.style.display = "block";
List를 보고 있는 메뉴의 상태를 생상에 따라 알려주고 있기 떄문에
class이름으로 스타일을 주고 제이쿼리를 사용하여
클릭에 따라 클래스의 이름을 변경 스타일이 변경될 수 있게 만들었습니다
}
const qnaListNBBtn = (qnaPagingPage, qnaSearch) => {
제목 / 내용 미리보기 상태의 페이징
맨위로 올라가는 상황을 방지하고자 ajax를 사용하였음
const qnaPage = qnaPagingPage;
사용자가 원하는 page의 nuber를 받아왔습니다
const q = qnaSearch;
사용자가 검색을 하는 경우를 대비해
검색어를 받아와줍니다 비어있는 경우,
controller에서 설정한 기본값으로 적용됩니다
const numResult = document.getElementById('ajax-numResult-numBtn');
페이징에 사용되는 number를 담고있는 태그의 객체
const backBtnResult = document.getElementById('backBtnResult');
페이징에 사용되는 "이전"버튼을 담고있는 태그의 객체
const nextBtnResult = document.getElementById('nextBtnResult');
페이징에 사용되는 "다음"버튼을 담고있는 태그의 객체
const previewTypeQna = document.getElementById('previewTypeQna');
제목/내용 미리보기 List를 담고있는 태그의 객체
$.ajax({
type: "post",
url: "/boardQna/UDPage",
data: {
"qnaPage": qnaPage,
"q": q
페이징에 사용되는 ajax이기 때문에
해당 페이지의 리스트와 검색어를 통한 리스트를
가져오기 위한 page , q 를 매개변수로 보내줍니다.
},
success: function (res) {
let outPut = "";
List정보를 문자열로 담아줄 output
let numPut = "";
하단의 페이징의 문자열을 number를 담아줄 numPut
let downPut = "";
"이전"버튼의 문자열을 담아줄 downPut
let upPut = "";
"다음"버튼의 문자열을 담아줄 upPut
downPut += '<a class="QnA-back-bnt-on" style="cursor: pointer;" onclick="qnaListNBBtn(' + (res.qnaBoardPage.page - 1) + ',' + res.qnaBoardPage.q + ')">이전</a>';
"이전"페이지로 넘어가는 버튼을 문자열로 표현하여 downPut에 담아줍니다
upPut += '<a class="QnA-next-bnt-on" style="cursor: pointer;" onclick="qnaListNBBtn(' + (res.qnaBoardPage.page + 1) + ',' + res.qnaBoardPage.q + ')">다음</a>';
"다음"페이지로 넘어가는 버턴을 문자열로 표현하여 upPut에 담아줍니다
for (let i in res.qnaBoardDTOList) {
List의 정보는 for문을 사용하여 뽑아줍니다
+=를 사용하여 이전에 안에 들어있던 무자열에 덮어씌어지는것을 방지하고 이어 붙여 담아줍니다.
outPut += '<div class="answer_box" style="border-top: 1px solid #cacccc;position: relative;">';
outPut += '<div class="tit_wrap">'
outPut += '<a href="/board/detail?BoardId=' + res.qnaBoardDTOList[i].id + '" target="_blank" class="tit_wrap_link_a">';
if(res.qnaBoardDTOList[i].boardPoint != 0){
글목록을 가져오며 해당 글에 걸려있는 POINT있다면 출력
걸려있는 POINT가 없다면 굳이 출력하지 않기위함
outPut += '<span class="power_grade" style="margin-right: 10px;" title="내공 전시장">'+ res.qnaBoardDTOList[i].boardPoint +'</span>';
}
outPut += '<span class=tit_txt">' + res.qnaBoardDTOList[i].boardTitle + '</span>';
outPut += '</a>';
outPut += '</div>';
outPut += '<div class="update_info">';
outPut += '<span class="num_answer">';
outPut += '답변 <em>' + res.qnaBoardDTOList[i].boardAnswer +'</em>';
outPut += '</span>';
outPut += '<span class="info">';
let nowTime = new Date().getTime(); // 현재 시간을 밀리초로 가져옴
let commentDate = new Date(res.qnaBoardDTOList[i].boardCreatedDate); // DTO의 boardCreatedDate를 JavaScript Date 객체로 변환
let timeDifference = (nowTime - commentDate) / (1000 * 60); // 분 단위로 시간 차이 계산
if (timeDifference <= 10) {
outPut += '방금 전';
} else if (timeDifference > 10 && timeDifference <= 60) {
outPut += moment(timeDifference) + '분 전';
} else if (timeDifference > 60 && timeDifference <= 60 * 24) {
timeDifference = (timeDifference / 60);
outPut += moment(timeDifference) + '시간 전';
} else if (timeDifference > 60 * 24 && timeDifference <= 60 * 24 * 30) {
timeDifference = (timeDifference / (60 * 24));
outPut += moment(timeDifference) + '일 전';
} else if (timeDifference > 60*24 && timeDifference <= 60*24*30){
outPut += moment(timeDifference) + '일 전';
} else {
outPut += moment(res.qnaBoardDTOList[i].boardCreatedDate).format("YYYY-MM-DD HH:mm");
}
글이 게시된 시간을 분 전 , 시간 전 , 일 전 으로 출력하기 위해
계산식을 사용하여 IF문을 통해 맞는 정보만 문자열에 추가합니다.
outPut += '</span>';
outPut += '</div>';
outPut += '</div>';
}
for (let i = res.qnaBoardPage.startPage; i <= res.qnaBoardPage.endPage; i++) {
하단에 보여질 number 숫자 버튼을 for문을 통해 출력하며
numPut에 저장합니다 .
if (res.qnaBoardPage.page == i) {
numPut += '<a class="QnA-paging-bnt-off">' + i + '</a>';
} else {
numPut += '<a class="QnA-paging-bnt-on" style="cursor: pointer;" onclick="qnaListNBBtn(' + i + ',' + res.qnaBoardPage.q + ')">' + i + '</a>';
}
for문을 통해 출력하며 사용자가 보아야하는 page와 같은 수라면
비활성화한 버튼태그를 담아줍니다.
}
if (res.qnaBoardPage.page <= 1) {
backBtnResult.innerHTML = "";
맨 마지막페이지라면 "다음" 버튼을 지웁니다.
} else {
backBtnResult.innerHTML = downPut;
맨 마지막 페이지가 아니라면 "다음"버튼의 문자열을 담은
변수를 해당 태그의 객체 innerHTML에 담아 출력합니다
}
if (res.qnaBoardPage.page == res.qnaBoardPage.maxPage) {
nextBtnResult.innerHTML = "";
처음 페이지라면 "이전" 버튼을 지웁니다.
} else if (res.qnaBoardPage.page != res.qnaBoardPage.maxPage) {
nextBtnResult.innerHTML = upPut;
처음 페이지가 아니라면 "이전" 버튼의 문자열을 담은
변수를 해당 태그의 객체 innerHTML에 담아 출력합니다
}
numResult.innerHTML = numPut;
ListResult.innerHTML = outPut;
위에서 담은 문자열의 변수를 객체로 만든 Result 객체의
innerHTML에 담아 출력합니다.
},
error: function () {
console.log("실패");
}
})
previewTypeQna.scrollIntoView({behavior: 'auto'});
페이징 버튼이 너무 아래있으면 다음페이지로 넘어가는 경우
List의 최상단으로 스크롤을 이동시킵니다.
}
</script>
- Controller
QnA페이지로 이동시 사용되는 GetMapping
@GetMapping("/board/Qna")
public String boardQna(@RequestParam(value = "qnaPage", required = false,defaultValue = "1")int qnaPage,
@RequestParam(value = "q",required = false,defaultValue = "") String q,
Model model,HttpSession session){
PageDTO qnaPageDTO = new PageDTO();
qnaPageDTO.setPage(qnaPage);
페이징에 사용되는 PageDTO
model.addAttribute("qnaBoardDTOList",boardService.qnaBoardList(qnaPageDTO,q));
페이징을통해 가져온 List를 담아주는 Model
model.addAttribute("qnaPaging",boardService.qnaPagingParam(qnaPageDTO,q));
페이징을통해 가져온 하단의 버튼정보를 담아주는 model
model.addAttribute("memberDTO", boardService.findById(session.getAttribute("memberId")));
QnA페이지 에서도 Header에 있는 Layout을 사용해야하기 때문에 사용자의 정보를 담아주는 model
return "/boardPage/boardQna";
}
QnA페이지의 ajax를 통한 페이징에 사용되는
PostMapping
@PostMapping("/boardQna/UDPage")
public ResponseEntity boardQnaUD(@RequestParam(value = "qnaPage", required = false,defaultValue = "1")int qnaPage,
@RequestParam(value = "q",required = false,defaultValue = "") String q) {
PageDTO qnaPageDTO = new PageDTO();
qnaPageDTO.setPage(qnaPage);
Map<String,Object> boardQnaResponse = new HashMap<>();
boardQnaResponse.put("qnaBoardDTOList",boardService.qnaBoardList(qnaPageDTO,q));
boardQnaResponse.put("qnaBoardPage",boardService.qnaPagingParam(qnaPageDTO,q));
Ajax가 사용되었기 떄문에 List와 paging 정보 2가지를 넘겨야 하는 상황으로
Map을 사용하여 하나로 압축하여 넘겨줍니다.
return new ResponseEntity<>(boardQnaResponse,HttpStatus.OK);
}
- Service
Main페이지인 index에서 사용된 QnA리스트와 페이징 메소드를 공유합니다
Main 페이지의 경우 전날 해설을 마쳤기 때문에 굳이 해설하지 않겠습니다
public Object qnaBoardList(PageDTO qnaPageDTO, String q) {
qnaPageDTO.setPageLimit(10);
qnaPageDTO.setQ(q);
List<BoardDTO> qnaBoardDTOList = boardRepository.qnaBoardDTOList(qnaPageDTO);
return qnaBoardDTOList;
}
public Object qnaPagingParam(PageDTO qnaPageDTO, String q) {
qnaPageDTO.setBlockLimit(10);
qnaPageDTO.setQ(q);
qnaPageDTO.setBoardCount(boardRepository.BoardCount(qnaPageDTO));
if (qnaPageDTO.getEndPage() > qnaPageDTO.getMaxPage()) {
qnaPageDTO.setEndPage(qnaPageDTO.getMaxPage());
}
return qnaPageDTO;
}
- Repository
Main페이지인 index에서 사용된 QnA리스트와 페이징 메소드를 공유합니다
Main페이지의 경우 전날 해설을 마쳤기 때문에 굳이 해설하지 않겠습니다.
public int BoardCount(PageDTO qnaPageDTO) {
if (!(qnaPageDTO.getQ().equals(""))) {
return sql.selectOne("naverBoard.BoardSearchCount", qnaPageDTO);
} else {
return sql.selectOne("naverBoard.BoardCount");
}
}
public List<BoardDTO> qnaBoardDTOList(PageDTO qnaPageDTO) {
if (!(qnaPageDTO.getQ().equals(""))) {
return sql.selectList("naverBoard.qnaSearchBoardList", qnaPageDTO);
} else {
return sql.selectList("naverBoard.qnaBoardList", qnaPageDTO);
}
}
- Mapper
Main페이지인 index에서 사용된 QnA리스트와 페이징 메소드를 공유합니다
Main페이지의 경우 전날 해설을 마쳤기 때문에 굳이 해설을하지 않겠습니다.
<select id="qnaBoardList" parameterType="page" resultType="board">
select * from board_table order by boardCreatedDate desc limit #{pageStart},#{pageLimit}
</select>
<select id="qnaSearchBoardList" parameterType="page" resultType="board">
select *
from board_table
where boardContents like concat('%', #{q}, '%') or boardTitle like concat('%', #{q}, '%')
order by id desc limit #{pageStart}, #{pageLimit}
</select>
<select id="BoardCount" resultType="Integer">
select count(id) from board_table
</select>
<select id="BoardSearchCount" parameterType="page" resultType="Integer">
select count(id)
from board_table
where boardContents like concat('%', #{q}, '%')
or boardTitle like concat('%', #{q}, '%')
</select>
'나의 수업일지' 카테고리의 다른 글
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (9) (0) | 2023.06.12 |
---|---|
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (8) (0) | 2023.06.11 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (6) (0) | 2023.06.09 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (5) (0) | 2023.06.09 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (4) (0) | 2023.06.07 |
- 네이버 지식인 QnA글 목록 화면



카테고리는 애초에 만들 생각이 없었기 때문에 지웠고
당연히 관심질문 등 유저의 정보를 나타내는 공간이 필요 없다고 생각하여 뺏습니다
또한 질문 게시판과 QnA게시판의 차이를 모르겠어서 그냥 QnA게시판만 만들기로 했습니다.
- boardQnA.jsp - script
main화면의 QnA 리스트와 크게 다른점이 없지만
제목으로만 보기 , 내용까지 보기 버튼을 추가했다는 약간의 차이점이 있습니다.
어떻게 만들어야할지 고민하다가 그냥 무식하고 편한 방법으로
2가지 상황의 Container를 2개 만들고,
버튼 클릭에 따라 display를 none / block으로 바뀌게 만들었습니다
<script>
const previewTypeQna = () => {
제목 / 내용 미리보기 List의 display를 변경해주는 함수
const previewTypeQna = document.getElementById('previewTypeQna');
내용까지 보기 display 변경을 위한 document 객체
const titleTypeQna = document.getElementById('titleTypeQna');
제목만 보기 display 변경을 위한 document 객체
const numResult = document.getElementById('numResult');
const ajaxNumResult = document.getElementById('ajax-numResult');
내용까지 보기 상태에서 다음페이지로 넘어가는 경우
인덱스의 qnaList와 마찬가지로 화면의 맨위로 올라가는 상황이였기 떄문에
페이징을 ajax와 일반 페이징으로 2가지 사용하였습니다.
$('#type_title').removeClass('type_title1');
$('#type_preview').removeClass('type_preview1');
$('#type_title').addClass('type_title');
$('#type_preview').addClass('type_preview');
previewTypeQna.style.display = "block";
numResult.style.display = "block";
titleTypeQna.style.display = "none";
ajaxNumResult.style.display = "none";
List를 보고 있는 메뉴의 상태를 생상에 따라 알려주고 있기 떄문에
class이름으로 스타일을 주고 제이쿼리를 사용하여
클릭에 따라 클래스의 이름을 변경 스타일이 변경될 수 있게 만들었습니다
}
const titleTypeQna = () => {
const titleTypeQna = document.getElementById('titleTypeQna');
제목만 보기 display 변경을 위한 document 객체
const previewTypeQna = document.getElementById('previewTypeQna');
내용까지 보기 display 변경을 위한 document 객체
const numResult = document.getElementById('numResult');
const ajaxNumResult = document.getElementById('ajax-numResult');
위의 설명과 마찬가지로 페이징을 보여주는 document 객체
$('#type_title').removeClass('type_title');
$('#type_preview').removeClass('type_preview');
$('#type_title').addClass('type_title1');
$('#type_preview').addClass('type_preview1');
previewTypeQna.style.display = "none";
numResult.style.display = "none";
titleTypeQna.style.display = "block";
ajaxNumResult.style.display = "block";
List를 보고 있는 메뉴의 상태를 생상에 따라 알려주고 있기 떄문에
class이름으로 스타일을 주고 제이쿼리를 사용하여
클릭에 따라 클래스의 이름을 변경 스타일이 변경될 수 있게 만들었습니다
}
const qnaListNBBtn = (qnaPagingPage, qnaSearch) => {
제목 / 내용 미리보기 상태의 페이징
맨위로 올라가는 상황을 방지하고자 ajax를 사용하였음
const qnaPage = qnaPagingPage;
사용자가 원하는 page의 nuber를 받아왔습니다
const q = qnaSearch;
사용자가 검색을 하는 경우를 대비해
검색어를 받아와줍니다 비어있는 경우,
controller에서 설정한 기본값으로 적용됩니다
const numResult = document.getElementById('ajax-numResult-numBtn');
페이징에 사용되는 number를 담고있는 태그의 객체
const backBtnResult = document.getElementById('backBtnResult');
페이징에 사용되는 "이전"버튼을 담고있는 태그의 객체
const nextBtnResult = document.getElementById('nextBtnResult');
페이징에 사용되는 "다음"버튼을 담고있는 태그의 객체
const previewTypeQna = document.getElementById('previewTypeQna');
제목/내용 미리보기 List를 담고있는 태그의 객체
$.ajax({
type: "post",
url: "/boardQna/UDPage",
data: {
"qnaPage": qnaPage,
"q": q
페이징에 사용되는 ajax이기 때문에
해당 페이지의 리스트와 검색어를 통한 리스트를
가져오기 위한 page , q 를 매개변수로 보내줍니다.
},
success: function (res) {
let outPut = "";
List정보를 문자열로 담아줄 output
let numPut = "";
하단의 페이징의 문자열을 number를 담아줄 numPut
let downPut = "";
"이전"버튼의 문자열을 담아줄 downPut
let upPut = "";
"다음"버튼의 문자열을 담아줄 upPut
downPut += '<a class="QnA-back-bnt-on" style="cursor: pointer;" onclick="qnaListNBBtn(' + (res.qnaBoardPage.page - 1) + ',' + res.qnaBoardPage.q + ')">이전</a>';
"이전"페이지로 넘어가는 버튼을 문자열로 표현하여 downPut에 담아줍니다
upPut += '<a class="QnA-next-bnt-on" style="cursor: pointer;" onclick="qnaListNBBtn(' + (res.qnaBoardPage.page + 1) + ',' + res.qnaBoardPage.q + ')">다음</a>';
"다음"페이지로 넘어가는 버턴을 문자열로 표현하여 upPut에 담아줍니다
for (let i in res.qnaBoardDTOList) {
List의 정보는 for문을 사용하여 뽑아줍니다
+=를 사용하여 이전에 안에 들어있던 무자열에 덮어씌어지는것을 방지하고 이어 붙여 담아줍니다.
outPut += '<div class="answer_box" style="border-top: 1px solid #cacccc;position: relative;">';
outPut += '<div class="tit_wrap">'
outPut += '<a href="/board/detail?BoardId=' + res.qnaBoardDTOList[i].id + '" target="_blank" class="tit_wrap_link_a">';
if(res.qnaBoardDTOList[i].boardPoint != 0){
글목록을 가져오며 해당 글에 걸려있는 POINT있다면 출력
걸려있는 POINT가 없다면 굳이 출력하지 않기위함
outPut += '<span class="power_grade" style="margin-right: 10px;" title="내공 전시장">'+ res.qnaBoardDTOList[i].boardPoint +'</span>';
}
outPut += '<span class=tit_txt">' + res.qnaBoardDTOList[i].boardTitle + '</span>';
outPut += '</a>';
outPut += '</div>';
outPut += '<div class="update_info">';
outPut += '<span class="num_answer">';
outPut += '답변 <em>' + res.qnaBoardDTOList[i].boardAnswer +'</em>';
outPut += '</span>';
outPut += '<span class="info">';
let nowTime = new Date().getTime(); // 현재 시간을 밀리초로 가져옴
let commentDate = new Date(res.qnaBoardDTOList[i].boardCreatedDate); // DTO의 boardCreatedDate를 JavaScript Date 객체로 변환
let timeDifference = (nowTime - commentDate) / (1000 * 60); // 분 단위로 시간 차이 계산
if (timeDifference <= 10) {
outPut += '방금 전';
} else if (timeDifference > 10 && timeDifference <= 60) {
outPut += moment(timeDifference) + '분 전';
} else if (timeDifference > 60 && timeDifference <= 60 * 24) {
timeDifference = (timeDifference / 60);
outPut += moment(timeDifference) + '시간 전';
} else if (timeDifference > 60 * 24 && timeDifference <= 60 * 24 * 30) {
timeDifference = (timeDifference / (60 * 24));
outPut += moment(timeDifference) + '일 전';
} else if (timeDifference > 60*24 && timeDifference <= 60*24*30){
outPut += moment(timeDifference) + '일 전';
} else {
outPut += moment(res.qnaBoardDTOList[i].boardCreatedDate).format("YYYY-MM-DD HH:mm");
}
글이 게시된 시간을 분 전 , 시간 전 , 일 전 으로 출력하기 위해
계산식을 사용하여 IF문을 통해 맞는 정보만 문자열에 추가합니다.
outPut += '</span>';
outPut += '</div>';
outPut += '</div>';
}
for (let i = res.qnaBoardPage.startPage; i <= res.qnaBoardPage.endPage; i++) {
하단에 보여질 number 숫자 버튼을 for문을 통해 출력하며
numPut에 저장합니다 .
if (res.qnaBoardPage.page == i) {
numPut += '<a class="QnA-paging-bnt-off">' + i + '</a>';
} else {
numPut += '<a class="QnA-paging-bnt-on" style="cursor: pointer;" onclick="qnaListNBBtn(' + i + ',' + res.qnaBoardPage.q + ')">' + i + '</a>';
}
for문을 통해 출력하며 사용자가 보아야하는 page와 같은 수라면
비활성화한 버튼태그를 담아줍니다.
}
if (res.qnaBoardPage.page <= 1) {
backBtnResult.innerHTML = "";
맨 마지막페이지라면 "다음" 버튼을 지웁니다.
} else {
backBtnResult.innerHTML = downPut;
맨 마지막 페이지가 아니라면 "다음"버튼의 문자열을 담은
변수를 해당 태그의 객체 innerHTML에 담아 출력합니다
}
if (res.qnaBoardPage.page == res.qnaBoardPage.maxPage) {
nextBtnResult.innerHTML = "";
처음 페이지라면 "이전" 버튼을 지웁니다.
} else if (res.qnaBoardPage.page != res.qnaBoardPage.maxPage) {
nextBtnResult.innerHTML = upPut;
처음 페이지가 아니라면 "이전" 버튼의 문자열을 담은
변수를 해당 태그의 객체 innerHTML에 담아 출력합니다
}
numResult.innerHTML = numPut;
ListResult.innerHTML = outPut;
위에서 담은 문자열의 변수를 객체로 만든 Result 객체의
innerHTML에 담아 출력합니다.
},
error: function () {
console.log("실패");
}
})
previewTypeQna.scrollIntoView({behavior: 'auto'});
페이징 버튼이 너무 아래있으면 다음페이지로 넘어가는 경우
List의 최상단으로 스크롤을 이동시킵니다.
}
</script>
- Controller
QnA페이지로 이동시 사용되는 GetMapping
@GetMapping("/board/Qna")
public String boardQna(@RequestParam(value = "qnaPage", required = false,defaultValue = "1")int qnaPage,
@RequestParam(value = "q",required = false,defaultValue = "") String q,
Model model,HttpSession session){
PageDTO qnaPageDTO = new PageDTO();
qnaPageDTO.setPage(qnaPage);
페이징에 사용되는 PageDTO
model.addAttribute("qnaBoardDTOList",boardService.qnaBoardList(qnaPageDTO,q));
페이징을통해 가져온 List를 담아주는 Model
model.addAttribute("qnaPaging",boardService.qnaPagingParam(qnaPageDTO,q));
페이징을통해 가져온 하단의 버튼정보를 담아주는 model
model.addAttribute("memberDTO", boardService.findById(session.getAttribute("memberId")));
QnA페이지 에서도 Header에 있는 Layout을 사용해야하기 때문에 사용자의 정보를 담아주는 model
return "/boardPage/boardQna";
}
QnA페이지의 ajax를 통한 페이징에 사용되는
PostMapping
@PostMapping("/boardQna/UDPage")
public ResponseEntity boardQnaUD(@RequestParam(value = "qnaPage", required = false,defaultValue = "1")int qnaPage,
@RequestParam(value = "q",required = false,defaultValue = "") String q) {
PageDTO qnaPageDTO = new PageDTO();
qnaPageDTO.setPage(qnaPage);
Map<String,Object> boardQnaResponse = new HashMap<>();
boardQnaResponse.put("qnaBoardDTOList",boardService.qnaBoardList(qnaPageDTO,q));
boardQnaResponse.put("qnaBoardPage",boardService.qnaPagingParam(qnaPageDTO,q));
Ajax가 사용되었기 떄문에 List와 paging 정보 2가지를 넘겨야 하는 상황으로
Map을 사용하여 하나로 압축하여 넘겨줍니다.
return new ResponseEntity<>(boardQnaResponse,HttpStatus.OK);
}
- Service
Main페이지인 index에서 사용된 QnA리스트와 페이징 메소드를 공유합니다
Main 페이지의 경우 전날 해설을 마쳤기 때문에 굳이 해설하지 않겠습니다
public Object qnaBoardList(PageDTO qnaPageDTO, String q) {
qnaPageDTO.setPageLimit(10);
qnaPageDTO.setQ(q);
List<BoardDTO> qnaBoardDTOList = boardRepository.qnaBoardDTOList(qnaPageDTO);
return qnaBoardDTOList;
}
public Object qnaPagingParam(PageDTO qnaPageDTO, String q) {
qnaPageDTO.setBlockLimit(10);
qnaPageDTO.setQ(q);
qnaPageDTO.setBoardCount(boardRepository.BoardCount(qnaPageDTO));
if (qnaPageDTO.getEndPage() > qnaPageDTO.getMaxPage()) {
qnaPageDTO.setEndPage(qnaPageDTO.getMaxPage());
}
return qnaPageDTO;
}
- Repository
Main페이지인 index에서 사용된 QnA리스트와 페이징 메소드를 공유합니다
Main페이지의 경우 전날 해설을 마쳤기 때문에 굳이 해설하지 않겠습니다.
public int BoardCount(PageDTO qnaPageDTO) {
if (!(qnaPageDTO.getQ().equals(""))) {
return sql.selectOne("naverBoard.BoardSearchCount", qnaPageDTO);
} else {
return sql.selectOne("naverBoard.BoardCount");
}
}
public List<BoardDTO> qnaBoardDTOList(PageDTO qnaPageDTO) {
if (!(qnaPageDTO.getQ().equals(""))) {
return sql.selectList("naverBoard.qnaSearchBoardList", qnaPageDTO);
} else {
return sql.selectList("naverBoard.qnaBoardList", qnaPageDTO);
}
}
- Mapper
Main페이지인 index에서 사용된 QnA리스트와 페이징 메소드를 공유합니다
Main페이지의 경우 전날 해설을 마쳤기 때문에 굳이 해설을하지 않겠습니다.
<select id="qnaBoardList" parameterType="page" resultType="board">
select * from board_table order by boardCreatedDate desc limit #{pageStart},#{pageLimit}
</select>
<select id="qnaSearchBoardList" parameterType="page" resultType="board">
select *
from board_table
where boardContents like concat('%', #{q}, '%') or boardTitle like concat('%', #{q}, '%')
order by id desc limit #{pageStart}, #{pageLimit}
</select>
<select id="BoardCount" resultType="Integer">
select count(id) from board_table
</select>
<select id="BoardSearchCount" parameterType="page" resultType="Integer">
select count(id)
from board_table
where boardContents like concat('%', #{q}, '%')
or boardTitle like concat('%', #{q}, '%')
</select>
'나의 수업일지' 카테고리의 다른 글
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (9) (0) | 2023.06.12 |
---|---|
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (8) (0) | 2023.06.11 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (6) (0) | 2023.06.09 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (5) (0) | 2023.06.09 |
인천 일보 아카데미 58~67일 차 개인 프로젝트 - NAVER 지식in 클론 코딩 (4) (0) | 2023.06.07 |