Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- JavaScript
- 항해99
- emqx
- EC2
- 카프카
- 스파르타코딩클럽
- DB
- Spring
- CentOS
- @jsonproperty
- docker
- 개인프로젝트
- 스프링의 정석
- java
- Spring Security
- 데이터베이스
- MYSQL
- 남궁성과 끝까지 간다
- 프로그래머스
- 생성자 주입
- WEB SOCKET
- Kafka
- AWS
- 웹개발
- 쇼트유알엘
- 스웨거
- visualvm
- JWT
- 시큐리티
- 패스트캠퍼스
Archives
- Today
- Total
Nellie's Blog
게시판 페이징 기능 구현 중 에러 (Uncaught SyntaxError: missing ) after argument list) 본문
Frond-end/javascript
게시판 페이징 기능 구현 중 에러 (Uncaught SyntaxError: missing ) after argument list)
Nellie Kim 2023. 9. 21. 11:49728x90
스크립트에서 화면으로 렌더링 하는 과정에서 에러가 발생한 듯하다..
에러메시지
: Uncaught SyntaxError: missing ) after argument list (at (색인):125:50)
BoardController
@GetMapping
public String getAllBoards2(@ModelAttribute("params") final SearchDto params, Model model) {
PagingResponse<BoardDto> response = boardService.findAllBoards(params);
model.addAttribute("boards", response);
model.addAttribute("params", params);
return "board";
}
board.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="com.fasterxml.jackson.databind.ObjectMapper" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>메인 화면</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- Your custom styles -->
<style>
.center-title {
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<!-- 마이페이지 버튼 -->
<div class="text-right mt-2">
<a href="/logout" class="btn btn-danger mr-2">로그아웃</a>
<a href="/mypage" class="btn btn-primary mr-2">마이페이지</a>
</div>
<br>
<br>
<br>
<br>
<h2 class="center-title">게시판</h2>
<!-- 로그인 사용자 이름 표시 -->
<%-- <div class="text-right mt-2">--%>
<%-- <span id="userName"></span> 님 안녕하세요!--%>
<%-- </div>--%>
<!-- 글 작성 버튼 -->
<a href="/boards/create" class="btn btn-primary mb-3">글 작성</a>
<!-- 글 목록 -->
<table class="table">
<thead>
<tr>
<th scope="col">제목</th>
<th scope="col">작성자</th>
<th scope="col">작성일</th>
</tr>
</thead>
<%-- <tbody>--%>
<%-- <c:forEach items="${boards.list}" var="board">--%>
<%-- <tr>--%>
<%-- <td><a href="/boards/${board.boardId}">${board.title}</a></td>--%>
<%-- <td>${board.nickname}</td>--%>
<%-- <td>${board.createdAt}</td>--%>
<%-- </tr>--%>
<%-- </c:forEach>--%>
<%-- </tbody>--%>
<!--/* 리스트 데이터 렌더링 영역 */-->
<tbody id="list">
</tbody>
</table>
<!--/* 페이지네이션 렌더링 영역 */-->
<div class="paging">
</div>
<br>
<br>
<!-- 글 목록 위 검색창 -->
<form action="/boards/search" method="GET" style="max-width: 300px; margin: 0 auto;">
<div class="input-group mb-3">
<input type="text" class="form-control" placeholder="검색어를 입력하세요" name="keyword" aria-label="검색어"
aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-primary" type="submit">검색</button>
</div>
</div>
</form>
<br>
<br>
<!-- 페이징 처리 -->
<div class="text-center" style="position: fixed; bottom: 60px; left: 50%; transform: translateX(-50%);">
<ul class="pagination">
<c:if test="${boards.pagination.existPrevPage}">
<li class="page-item"><a class="page-link" href="/boards?page=${boards.pagination.startPage - 1}">이전</a>
</li>
</c:if>
<c:forEach begin="${boards.pagination.startPage}" end="${boards.pagination.endPage}" var="page">
<li class="page-item <c:if test='${page == boards.pagination.currentPage}'>active</c:if>'">
<a class="page-link" href="/boards?page=${page}">${page}</a>
</li>
</c:forEach>
<c:if test="${boards.pagination.existNextPage}">
<li class="page-item"><a class="page-link" href="/boards?page=${boards.pagination.endPage + 1}">다음</a>
</li>
</c:if>
</ul>
</div>
</div>
<script>
window.onload = function () {
// 페이지가 로드되었을 때, 딱 한 번만 함수를 실행
findAllPost();
};
// 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊 함수 1. 게시글 리스트 조회 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊
function findAllPost() {
// 1. PagingResponse의 멤버인 List<T> 타입의 list를 의미
var list = ${boards.list};
// 2. 리스트가 비어있는 경우, 행에 "검색 결과가 없다"는 메시지를 출력하고, 페이지 번호(페이지네이션) HTML을 제거(초기화)한 후 로직을 종료
if (list.length === 0) {
document.getElementById('list').innerHTML = '<td colspan="6"><div class="no_data_msg">검색된 결과가 없습니다.</div></td>';
drawPage();
return;
}
// 3. PagingResponse의 멤버인 pagination을 의미
var pagination = ${boards.pagination};
// 4. @ModelAttribute를 이용해서 뷰(HTML)로 전달한 SearchDto 타입의 객체인 params를 의미
var params = ${params};
// 5. 리스트에 출력되는 게시글 번호를 처리하기 위해 사용되는 변수 (리스트에서 번호는 페이지 정보를 이용해서 계산해야 함)
var num = pagination.totalRecordCount - ((params.currentPage - 1) * params.recordSize); // 전체 데이터 수 - ( 현재 페이지 수 - 1 ) * 페이지당 출력 게시물 수 // 현재가 1페이지이면 20, 2페이지이면 10
// 6. 리스트 데이터 렌더링
drawList(list, num);
// 7. 페이지 번호 렌더링
drawPage(pagination, params);
}
// 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊 함수 2. 리스트 HTML draw 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊
// 함수 2. 리스트 HTML draw
function drawList(list, num) {
// 1. 렌더링 할 HTML을 저장할 변수
var html = '';
// 2. 리스트 데이터를 JSP 태그를 사용하여 동적으로 생성
<c:forEach items="${boards.list}" var="board">
html += '<tr>';
html += '<td><input type="checkbox" /></td>';
html += '<td class="tl"><a href="/boards/${board.boardId}">${board.title}</a></td>';
html += '<td>${board.nickname}</td>';
html += '<td>${board.createdAt}</td>';
html += '</tr>';
</c:forEach>;
// 3. id가 "list"인 요소를 찾아 HTML을 렌더링
document.getElementById('list').innerHTML = html;
}
// 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊 함수 3. 페이지 HTML draw 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊
function drawPage(pagination, params) {
// 1. 필수 파라미터가 없는 경우, 페이지 번호(페이지네이션) HTML을 제거(초기화)한 후 로직 종료
if (!pagination || !params) {
document.querySelector('.paging').innerHTML = '';
throw new Error('Missing required parameters...');
}
// 2. 렌더링 할 HTML을 저장할 변수
var html = '';
// 3. 이전 페이지가 있는 경우, 즉 시작 페이지(startPage)가 1이 아닌 경우 첫 페이지 버튼과 이전 페이지 버튼을 HTML에 추가
if (pagination.existPrevPage) {
html += '<a href="javascript:void(0);" onclick="movePage(1)" class="page_bt first">첫 페이지</a>';
html += '<a href="javascript:void(0);" onclick="movePage(' + (pagination.startPage - 1) + ')" class="page_bt prev">이전 페이지</a>';
}
/*
* 4. 시작 페이지(startPage)와 끝 페이지(endPage) 사이의 페이지 번호(i)를 넘버링 하는 로직
* 페이지 번호(i)와 현재 페이지 번호(params.page)가 동일한 경우, 페이지 번호(i)를 활성화(on) 처리
*/
html += '<p>';
for (var i = pagination.startPage; i <= pagination.endPage; i++) {
html += (i !== params.currentPage)
? '<a href="javascript:void(0);" onclick="movePage(' + i + ');">' + i + '</a>'
: '<span class="on">' + i + '</span>';
}
html += '</p>';
// 5. 현재 위치한 페이지 뒤에 데이터가 더 있는 경우, 다음 페이지 버튼과 끝 페이지 버튼을 HTML에 추가
if (pagination.existNextPage) {
html += '<a href="javascript:void(0);" onclick="movePage(' + (pagination.endPage + 1) + ');" class="page_bt next">다음 페이지</a>';
html += '<a href="javascript:void(0);" onclick="movePage(' + pagination.totalPageCount + ');" class="page_bt last">마지막 페이지</a>';
}
// 6. class가 "paging"인 요소를 찾아 HTML을 렌더링
document.querySelector('.paging').innerHTML = html;
}
// 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊 함수 4. 페이지 이동 😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊
function movePage(page) {
// 1. drawPage( )의 각 버튼에 선언된 onclick 이벤트를 통해 전달받는 page(페이지 번호)를 기준으로 객체 생성
var queryParams = {
page: (page) ? page : 1,
recordSize: 10,
pageSize: 10
};
/*
* new URLSearchParams(queryParams).toString() : queryParams의 모든 프로퍼티(key-value)를 쿼리 스트링으로 변환
* URI + 쿼리 스트링에 해당하는 주소로 이동
* (해당 함수가 리턴해주는 값을 브라우저 콘솔(console)에 찍어보시면 쉽게 이해하실 수 있습니다.)
*/
location.href = '/boards?' + new URLSearchParams(queryParams).toString();
}
</script>
</body>
</html>
BoardMapper.xml
<!-- 게시글 리스트 조회 -->
<select id="findAllBoards" parameterType="com.example.first.dto.SearchDto" resultType="com.example.first.dto.BoardDto">
SELECT *
FROM postgres.first_project.boards
LIMIT #{recordSize} OFFSET #{pagination.limitStart}
</select>
PagingResponse
@Getter
public class PagingResponse<T> {
private List<BoardDto> list = new ArrayList<>();
private Pagination pagination;
public PagingResponse(List<BoardDto> list, Pagination pagination) {
this.list.addAll(list);
this.pagination = pagination;
}
}
Pagination
package com.example.first.dto;
import lombok.Getter;
@Getter
public class Pagination {
private int currentPage; // 현재 페이지 번호
private int totalRecordCount; // 전체 데이터 수
private int totalPageCount; // 전체 페이지 수
private int startPage; // 첫 페이지 번호
private int endPage; // 끝 페이지 번호
private int limitStart; // LIMIT 시작 위치
private boolean existPrevPage; // 이전 페이지 존재 여부
private boolean existNextPage; // 다음 페이지 존재 여부
public Pagination(int totalRecordCount, SearchDto params) {
if (totalRecordCount > 0) {
this.totalRecordCount = totalRecordCount;
calculation(params);
}
}
private void calculation(SearchDto params) {
// 전체 페이지 수 계산
totalPageCount = ((totalRecordCount - 1) / params.getRecordSize()) + 1;
// 현재 페이지 번호가 전체 페이지 수보다 큰 경우, 현재 페이지 번호에 전체 페이지 수 저장
if (params.getCurrentPage() > totalPageCount) {
params.setCurrentPage(totalPageCount);
this.currentPage = totalPageCount;
}
// 첫 페이지 번호 계산
startPage = ((params.getCurrentPage() - 1) / params.getPageSize()) * params.getPageSize() + 1;
// 끝 페이지 번호 계산
endPage = startPage + params.getPageSize() - 1;
// 끝 페이지가 전체 페이지 수보다 큰 경우, 끝 페이지 전체 페이지 수 저장
if (endPage > totalPageCount) {
endPage = totalPageCount;
}
// LIMIT 시작 위치 계산
limitStart = (params.getCurrentPage() - 1) * params.getRecordSize();
// 이전 페이지 존재 여부 확인
existPrevPage = startPage != 1;
// 다음 페이지 존재 여부 확인
existNextPage = (endPage * params.getRecordSize()) < totalRecordCount;
}
}
SearchDto
@Getter
@Setter
public class SearchDto {
private int currentPage; // 현재 페이지 번호
private int recordSize; // 페이지당 출력할 데이터 개수
private int pageSize; // 화면 하단에 출력할 페이지 사이즈
private String keyword; // 검색 키워드
private String searchType; // 검색 유형
private Pagination pagination; // 페이지네이션 정보
public SearchDto() {
this.currentPage = 1;
this.recordSize = 10;
this.pageSize = 10;
}
}
'Frond-end > javascript' 카테고리의 다른 글
아파치 이차트(Apache ECharts) 란? (0) | 2023.11.07 |
---|---|
게시판 페이징 기능 구현 중 board.jsp 중간 기록 (0) | 2023.09.21 |
ajax xhr서버 요청 실패 에러/ 회원가입 최종성공 jsp코드 (0) | 2023.09.13 |
[JQuery] 제이쿼리 자주 쓰는 함수 모음 (0) | 2022.09.20 |
[javascript] 자바스크립트 기본 문법 정리 (java와 비교하며 작성) (6) | 2022.09.16 |