자바스크립트

 

 

export default class PageMaker {
    constructor(page = 1, perPageNum = 10) {
        this.page = page; // 현재 페이지
        this.perPageNum = perPageNum; // 페이지당 항목 수
        this.pageStart = 0; // 페이지 시작 인덱스
        this.totalCount = 0; // 전체 항목 수
        this.startPage = 1; // 시작 페이지
        this.endPage = 1; // 끝 페이지
        this.prev = false; // 이전 페이지 여부
        this.next = false; // 다음 페이지 여부
        this.displayPageNum = 10; // 하단 페이지 번호 표시 수
        this.tempEndPage = 1; // 임시 끝 페이지
        this.calcData(); // 페이지 계산 초기화
    }

    // 페이지 설정
    setPage(page) {
        if (page <= 0) {
            this.page = 1;
        } else {
            this.page = page;
        }
        this.pageStart = (this.page - 1) * this.perPageNum;
    }

    // 페이지당 항목 수 설정
    setPerPageNum(perPageNum) {
        if (perPageNum <= 0 || perPageNum > 100) {
            this.perPageNum = 10;
        } else {
            this.perPageNum = perPageNum;
        }
        this.pageStart = (this.page - 1) * this.perPageNum;
    }

    // 전체 항목 수 설정 및 페이지 계산
    setTotalCount(totalCount) {
        this.totalCount = totalCount;
        this.calcData();
    }

    // 페이지 계산
    calcData() {
        this.endPage = Math.ceil(this.page / this.displayPageNum) * this.displayPageNum;
        this.startPage = this.endPage - this.displayPageNum + 1;
        this.tempEndPage = Math.ceil(this.totalCount / this.perPageNum);
        
        if (this.endPage > this.tempEndPage) {
            this.endPage = this.tempEndPage;
        }
        
        this.prev = this.startPage > 1;
        this.next = this.endPage * this.perPageNum < this.totalCount;
    }

    // 쿼리 문자열 생성
    makeQuery(page) {
        const params = new URLSearchParams();
        params.append('page', page);
        params.append('perPageNum', this.perPageNum);
        return params.toString();
    }

    // 페이지네이션 HTML 생성
    bootStrapPagingHTML(url) {
        let html = "<ul class='pagination'>";
        if (this.prev) {
            html += `<li><a href='${url}?${this.makeQuery(1)}'>처음</a></li>`;
        }

        if (this.prev) {
            html += `<li><a href='${url}?${this.makeQuery(this.startPage - 1)}'>&laquo;</a></li>`;
        }

        for (let i = this.startPage; i <= this.endPage; i++) {
            const active = this.page === i ? "class='active'" : "";
            html += `<li ${active}><a href='${url}?${this.makeQuery(i)}'>${i}</a></li>`;
        }

        if (this.next) {
            html += `<li><a href='${url}?${this.makeQuery(this.endPage + 1)}'>&raquo;</a></li>`;
        }

        if (this.next) {
            html += `<li><a href='${url}?${this.makeQuery(this.tempEndPage)}'>마지막</a></li>`;
        }

        html += "</ul>";
        return html;
    }
}

 

 

타입스트립트 적용

export default class  PageMaker {
  private page: number;
  private perPageNum: number;
  private pageStart: number;
  private totalCount: number;
  private startPage: number;
  private endPage: number;
  private prev: boolean;
  private next: boolean;
  private displayPageNum: number;
  private tempEndPage: number;

  constructor(page: number = 1, perPageNum: number = 10) {
    this.page = page; // 현재 페이지
    this.perPageNum = perPageNum; // 페이지당 항목 수
    this.pageStart = 0; // 페이지 시작 인덱스
    this.totalCount = 0; // 전체 항목 수
    this.startPage = 1; // 시작 페이지
    this.endPage = 1; // 끝 페이지
    this.prev = false; // 이전 페이지 여부
    this.next = false; // 다음 페이지 여부
    this.displayPageNum = 10; // 하단 페이지 번호 표시 수
    this.tempEndPage = 1; // 임시 끝 페이지
    this.calcData(); // 페이지 계산 초기화
  }

  setPage(page: number): void {
    if (page <= 0) {
      this.page = 1;
    } else {
      this.page = page;
    }
    this.pageStart = (this.page - 1) * this.perPageNum;
  }

  setPerPageNum(perPageNum: number): void {
    if (perPageNum <= 0 || perPageNum > 100) {
      this.perPageNum = 10;
    } else {
      this.perPageNum = perPageNum;
    }
    this.pageStart = (this.page - 1) * this.perPageNum;
  }

  setTotalCount(totalCount: number): void {
    this.totalCount = totalCount;
    this.calcData();
  }

  private calcData(): void {
    this.endPage =
      Math.ceil(this.page / this.displayPageNum) * this.displayPageNum;
    this.startPage = this.endPage - this.displayPageNum + 1;
    this.tempEndPage = Math.ceil(this.totalCount / this.perPageNum);

    if (this.endPage > this.tempEndPage) {
      this.endPage = this.tempEndPage;
    }

    this.prev = this.startPage > 1;
    this.next = this.endPage * this.perPageNum < this.totalCount;
  }

  getPageStart(): number {
    return this.pageStart;
  }

  getPerPageNum(): number {
    return this.perPageNum;
  }

  private makeQuery(page: number): string {
    const params = new URLSearchParams();
    params.append("page", page.toString());
    params.append("perPageNum", this.perPageNum.toString());
    return params.toString();
  }

  bootStrapPagingHTML(url: string): string {
    let html = "<ul class='pagination'>";
    if (this.prev) {
      html += `<li><a href='${url}?${this.makeQuery(1)}'>처음</a></li>`;
    }

    if (this.prev) {
      html += `<li><a href='${url}?${this.makeQuery(
        this.startPage - 1
      )}'>&laquo;</a></li>`;
    }

    for (let i = this.startPage; i <= this.endPage; i++) {
      const active = this.page === i ? "class='active'" : "";
      html += `<li ${active}><a href='${url}?${this.makeQuery(
        i
      )}'>${i}</a></li>`;
    }

    if (this.next) {
      html += `<li><a href='${url}?${this.makeQuery(
        this.endPage + 1
      )}'>&raquo;</a></li>`;
    }

    if (this.next) {
      html += `<li><a href='${url}?${this.makeQuery(
        this.tempEndPage
      )}'>마지막</a></li>`;
    }

    html += "</ul>";
    return html;
  }
}

 

 

주요 사항:

  1. 생성자: 클래스 생성자에서 페이지와 페이지당 항목 수를 초기화합니다.
  2. setPage 및 setPerPageNum: 페이지와 페이지당 항목 수를 설정하며, 이를 통해 pageStart를 계산합니다.
  3. setTotalCount: 전체 항목 수를 설정하고 페이지 정보를 계산합니다.
  4. calcData: 페이지 계산 로직을 처리합니다.
  5. makeQuery: URL 쿼리 문자열을 생성합니다.
  6. bootStrapPagingHTML: 페이지네이션 HTML을 생성합니다.

이 JavaScript 클래스는 Java 페이지 처리 클래스의 기능을 JavaScript로 구현하여 페이지네이션을 처리할 수 있도록 합니다.

 

 

 

 

 

예제 코드

 

// 페이지네이션 설정
const pageMaker = new PageMaker();

// 전체 항목 수 설정 (예: 123개의 항목이 있다고 가정)
pageMaker.setTotalCount(123);

// 페이지당 항목 수 설정 (예: 10개 항목을 한 페이지에 표시)
pageMaker.setPerPageNum(10);

// 현재 페이지 설정 (예: 5페이지)
pageMaker.setPage(5);

// 페이지네이션 HTML 생성
const url = "/items"; // 페이지네이션 링크의 기본 URL
const paginationHTML = pageMaker.bootStrapPagingHTML(url);

// 생성된 페이지네이션 HTML을 웹 페이지에 삽입
document.getElementById("pagination").innerHTML = paginationHTML;

 

다음과 같이 사용할것

  const pageMaker = new PageMaker(Number(page), Number(pageSize));
  pageMaker.setTotalCount(totalItems);
  pageMaker.setPage(Number(page));
  const pageStart = pageMaker.getPageStart();
  const perPageNum = pageMaker.getPerPageNum();
  console.log(" 현재 페이지  :", page, pageStart, perPageNum);

 

 

 

Express  샘플

 

import db from "@/lib/mysqldb";
import PageMaker from "@/util/pageMaker";


export interface PropertyDTO {
  num: number;
  propertyId: number;
  ownerId: number;
  name: string;
  type: string;
  description: string;
  address1: string;
  address2: string;
  address3: string;
  zipcode: string;
  beds: number;
  baths: number;
  squareFeet: number;
  nightlyRate: number;
  weeklyRate: number;
  monthlyRate: number;
  sellerName: string;
  sellerEmail: string;
  sellerPhone: string;
  isFeatured: boolean;
  amenities: string[];
  images: string[];
  regTime: Date;
  updateTime: Date;
}

const SELECT_PROPERTY_QUERY = `
SELECT 
    p.property_id AS propertyId,
    p.owner_id AS ownerId,
    p.name,
    p.type,
    p.description,
    p.address1,
    p.address2,
    p.address3,
    p.zipcode,
    p.beds,
    p.baths,
    p.square_feet AS squareFeet,
    p.nightly_rate AS nightlyRate,
    p.weekly_rate AS weeklyRate,
    p.monthly_rate AS monthlyRate,
    p.seller_name AS sellerName,
    p.seller_email AS sellerEmail,
    p.seller_phone AS sellerPhone,
    p.is_featured AS isFeatured,
    p.reg_time AS regTime,
    p.update_time AS updateTime,
    GROUP_CONCAT(DISTINCT pa.amenity ORDER BY pa.amenity SEPARATOR ', ') AS amenities,
    GROUP_CONCAT(DISTINCT pi.images ORDER BY pi.images SEPARATOR ', ') AS images
FROM property p
LEFT JOIN property_amenities pa ON p.property_id = pa.property_id
LEFT JOIN property_images pi ON p.property_id = pi.property_id
GROUP BY p.property_id
`;










export async function selectPropertiesTotalModel(keyword: string | undefined, searchType: string | undefined): Promise<number> {
  let query = `SELECT count(*) as total FROM 
                (
                  ${SELECT_PROPERTY_QUERY}
                ) RR  WHERE RR.propertyId > 0`;

  const params: (string | number)[] = [];

  let {query: q, params: p} = searchQuery(query, params, keyword, searchType);

  const [rows] = await db.query(q, p);
  return rows[0].total as number;
}





//전체 목록

export async function selectSearchAllPropertiesModel(
  keyword: string | undefined,  
  searchType: string | undefined,
  page: string | undefined,
  pageSize: string | undefined
){
  const totalItems = await selectPropertiesTotalModel(keyword, searchType);
  if (!totalItems) return null;

  if(!page) page = "1";
  if(!pageSize) pageSize = "6";

 // console.log(" 2 selectSearchAllPropertiesModel : ", keyword, searchType, page, pageSize);
  
  const pageMaker = new PageMaker(Number(page), Number(pageSize));
  pageMaker.setTotalCount(totalItems);
  pageMaker.setPage(Number(page));
  const pageStart = pageMaker.getPageStart();
  const perPageNum = pageMaker.getPerPageNum();
  console.log(" 현재 페이지  :", page, pageStart, perPageNum);


  let query = `SELECT  RRR.* FROM ( 
                    SELECT   @rownum := @rownum + 1 AS num,   RR.*   FROM 
                    (
                      ${SELECT_PROPERTY_QUERY}
                    ) RR ,
                    (SELECT @rownum :=0) AS r
                    WHERE RR.propertyId > 0`;

  const params: (string | number)[] = [];
  const { query: q, params: p } = searchQuery(query, params, keyword, searchType);  
  

  const finalQuery = `${q} ORDER BY RR.propertyId ASC 
        ) RRR  ORDER by RRR.num DESC  
        LIMIT ? , ?`;

  p.push(pageStart, perPageNum);
  const [rows] = await db.query(finalQuery, p);

  let rowsData: PropertyDTO[] | null = null;
  if (rows && Array.isArray(rows)) {
    rowsData = rows.map(property => {
      property.amenities = property.amenities ? property.amenities.toString().split(',').map((item: string) => item.trim()) : [];
      property.images = property.images ? property.images.toString().split(',').map((item: string) => item.trim()) : [];
      return property;
    });
  }

  if (!rowsData) {
    console.error("No properties found or failed to process the data.");
    return null; // or you might want to return an empty array instead of null
  }

  return { rowsData, pageMaker };
}




function searchQuery(query:string,params:(string | number)[], keyword:string|undefined, searchType:string|undefined): {query:string, params:(string | number)[]} {
  if (keyword) {
    query += ` 
        AND (address1 LIKE ? OR address2 LIKE ? OR address3 LIKE ? 
        OR zipcode LIKE ? OR name LIKE ?)`;
    
    params.push(`%${keyword}%`, `%${keyword}%`, `%${keyword}%`, `%${keyword}%`, `%${keyword}%`);
    
    if (searchType && searchType !== "All") {
      query += ` AND RR.type = ?`;
      params.push(searchType);
    } 
  }
  
  return {query ,params};
}

 

 

 

 

 

 

HTML 구조

HTML 페이지에 pagination이라는 ID를 가진 요소를 추가합니다. 페이지네이션 HTML이 이 요소에 삽입됩니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pagination Example</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
    <div id="pagination"></div>

    <script src="path/to/your/PageMaker.js"></script>
    <script>
        // 페이지네이션 사용 예
        const pageMaker = new PageMaker();
        pageMaker.setTotalCount(123);
        pageMaker.setPerPageNum(10);
        pageMaker.setPage(5);
        const url = "/items";
        const paginationHTML = pageMaker.bootStrapPagingHTML(url);
        document.getElementById("pagination").innerHTML = paginationHTML;
    </script>
</body>
</html>

 

주요 단계

  1. PageMaker 객체 생성: 페이지네이션 기능을 처리하기 위한 PageMaker 객체를 생성합니다.
  2. 항목 수 설정: 전체 항목 수를 설정합니다.
  3. 페이지당 항목 수 설정: 한 페이지에 표시할 항목 수를 설정합니다.
  4. 현재 페이지 설정: 현재 페이지를 설정합니다.
  5. 페이지네이션 HTML 생성: 페이지네이션 링크가 포함된 HTML 문자열을 생성합니다.
  6. HTML 삽입: 생성된 페이지네이션 HTML을 웹 페이지의 적절한 위치에 삽입합니다.

이 예제는 기본적인 페이지네이션을 구현하며, 실제 웹 애플리케이션에서는 서버에서 데이터와 페이지 정보를 가져와서 이 클래스를 활용할 수 있습니다.

 

 

 

 

 

 

넥스트 페이징 처리

 

https://macaronics.net/m04/react/view/2268

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

about author

PHRASE

Level 60  라이트

사랑은 이상한 안경을 쓰고 있다. 구리를 황금으로, 가난함을 풍족하게 보이게 하는 안경을 끼고 있다. 그러기 때문에 눈에 난 다래끼조차도 진주알 같이 보이고 만다. -세르반테스

댓글 ( 0)

댓글 남기기

작성