본문 바로가기
실전 코딩/javascript · jquery

게시판과 페이지네이션까지 구현해보기

by 정리무새 2022. 2. 12.
728x90
반응형

게시판/페이지네이션의 기능이 필요하지 않다해도

따라하다보면 스크립트에 대한 이해도가 조금씩 생기지 않을까 싶어

이리저리 알아보며 만든 게시판 만들기의 코드를 정리할까 한다. 

혹여 따라하는 분들이 있으면 태그이름이나 스크립트 경로 이런건 입맛대로 바꾸면 될것 같다.

 

HTML

<!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>
    <style>
        @font-face {
            font-family: 'GowunDodum-Regular';
            src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2108@1.1/GowunDodum-Regular.woff') format('woff');
            font-weight: normal;
            font-style: normal;
        }
        #wrap {max-width: 800px; margin: 0 auto 150px; font-family: 'GowunDodum-Regular'; font-size: 18px; text-align: center;}
        h1 {background: #e3f2fd; padding: 5px 0; border-radius: 10px;}
        a {text-decoration: none; cursor: pointer; display: inline-block; margin: 0 5px;}
        .table {width: 100%; border: 1px solid #ddd; border-collapse: collapse; margin: 50px auto 40px;}
        .table thead {background: #e3f2fd;}
        .table tr:not(:last-child) {border-bottom: 1px solid #ddd;}
        .table tr th,
        .table tr td {padding: 10px 15px; text-align: center; text-transform: uppercase;}
        .select-wrap {text-align: right; margin: 30px 0 0;}
        .select-wrap select {width: 150px; height: 35px; border-radius: 5px; padding: 0 5px; border: 1px solid #aaa; color: #202020; font-size: 16px;}
        /* 공통 : 페이징 */
        #pagenav {display: flex; justify-content: center; align-items: center; font-size: 1rem; border-width: 3px;}
        #pagenav a {width: 32px; line-height: 30px; margin: 0 3px; color: #0c0b0f; text-align: center; border-radius: 10px; font-weight: bold; border: 1px solid transparent; transition: all .2s;}
        #pagenav .arrow {background: #e3f2fd; letter-spacing: -2px;}
        #pagenav .pg-link.on {color: #fff; background: #90caf9;}
        #pagenav .pg-link:not(.disabled, .on):hover {background: #eee;}
    </style>
</head>
<body>
    <div id="wrap">
        <h1>랭킹 리스트</h1>
        <div class="select-wrap">
            <select id="data-per-page">
                <!-- <option value="5" selected="selected">5</option>
                <option value="10">10</option>
                <option value="15">15</option> -->
            </select>
        </div>
        <table id="rankings-table" class="table paginated">
            <colgroup>
                <col style="width: auto;">
                <col style="width: auto;">
                <col style="width: auto;">
            </colgroup>
            <thead>
                <tr>
                    <th>Ranking</th>
                    <th>Full Name</th>
                    <th>Points</th>
                </tr>
            </thead>
            <tbody>
                <!-- to be filled by javascript -->
            </tbody>
        </table>
        <div id="pagenav"></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script type="text/javascript" src="./paging.js"></script>
</body>
</html>

 

구조와 css는 이정도로 하고

우선 데이터 파일이 필요하기 때문에 데이터 파일을 만들어야 한다.

파일은 Ajax로 끌어오느라 .json 파일로 만들었다.

 

아래와 같은 json형식으로 데이터를 만들고 rankings.json 이라고 파일명을 정했다.

[
    {
        "rank" : "1",
        "name" : "Jhon",
        "total" : 5500
    },
    {
        "rank" : "2",
        "name" : "may",
        "total" : 5000
    },
    {
        "rank" : "3",
        "name" : "sery",
        "total" : 4805
    },
    {
        "rank" : "4",
        "name" : "jonadan",
        "total" : 4625
    },
    {
        "rank" : "5",
        "name" : "july",
        "total" : 4212
    },
    {
        "rank" : "6",
        "name" : "pio",
        "total" : 3050
    },
    {
        "rank" : "7",
        "name" : "Jhon",
        "total" : 3000
    },
    {
        "rank" : "8",
        "name" : "Jhon",
        "total" : 2850
    },
    {
        "rank" : "9",
        "name" : "Jhon",
        "total" : 2135
    },
    {
        "rank" : "10",
        "name" : "Jhon",
        "total" : 572
    },
    {
        "rank" : "11",
        "name" : "pio",
        "total" : 3050
    },
    {
        "rank" : "12",
        "name" : "Jhon",
        "total" : 3000
    },
    {
        "rank" : "13",
        "name" : "Jhon",
        "total" : 2850
    },
    {
        "rank" : "14",
        "name" : "Jhon",
        "total" : 2135
    },
    {
        "rank" : "15",
        "name" : "Jhon",
        "total" : 572
    },
    {
        "rank" : "16",
        "name" : "Jhon",
        "total" : 2850
    },
    {
        "rank" : "17",
        "name" : "Jhon",
        "total" : 2135
    },
    {
        "rank" : "18",
        "name" : "Jhon",
        "total" : 572
    },
    {
        "rank" : "19",
        "name" : "Jhon",
        "total" : 459
    },
    {
        "rank" : "20",
        "name" : "Jhon",
        "total" : 320
    },
    {
        "rank" : "21",
        "name" : "Jhon",
        "total" : 315
    },
    {
        "rank" : "22",
        "name" : "Jhon",
        "total" : 215
    },
    {
        "rank" : "23",
        "name" : "Jhon",
        "total" : 100
    },
    {
        "rank" : "24",
        "name" : "Amy",
        "total" : 53
    }
]

 

그리고 이제 제일 중요한 스크립트 부분!!

$(function(){
	// for문으로 select에 5단위로 option태그를 넣어준다.
    var option = '';
    for(var i = 5; i <= 25; i += 5) {
        option += '<option value="'+ i + '">'+ i +'</option>';
    }
    $('#data-per-page').html(option);

    var pginfo = {
        total : 0,	// 데이터 총 개수
        cp : 1,		// 현재페이지
        pgCnt : 3,	// 페이지를 몇개씩 보여줄것인지
        listCnt : $('#data-per-page').val();  // 리스트를 몇개씩 보여줄 것인지
    } //pginfo에 변수들을 담아놓았다. (나중에 재활용하기 용이)

    function ranking() {
        var request = new XMLHttpRequest;  // 새로고침없이도 URL로부터 데이터를 받아올 수 있다.

        request.open('get', './rankings.json');  // Ajax로 .json파일을 get방식으로 불러오기
        request.onload = function() {
            try {
                var parse = JSON.parse(request.responseText);
                pginfo.total = parse.length;	// json파일의 총 데이터 개수가 된다.
                list(parse);
            } catch(err) {
                console.log('not loading');     // 데이터 로딩에 실패시 알 수 있게 체크
            }
        }
        request.send();
    }

    function list(obj) { //obj에는 위에 json파일을 파싱한 데이터가 담긴다.
        var total = pginfo.total;	// 총 리스트의 개수
        var cp = pginfo.cp;			// 현재 페이지(current page)
        var pgCnt = pginfo.pgCnt;	// 페이지 카운트(페이지 숫자를 몇개씩 보여줄것인지)
        var listCnt = pginfo.listCnt;	// 리스트 카운트(리스트를 몇개씩 보여줄것인지)
        var totalPage = Math.ceil(total/listCnt);	// 총 페이지 수 ex) 1 2 3 4 5 총 5개
        var totalBlock = Math.ceil(totalPage/pgCnt);
        // ↖총 페이지의 묶음 수 ex) 페이지네이션을 3개씩 보여주면 123이 한 묶음이다.
        var sPage = 0;			// 처음 페이지 ex) 1 2 3에 1이 해당
        var ePage = 0;			// 끝 페이지 ex) 1 2 3에 3이 해당
        function renderTable() {
            renderList();	// 리스트 관련 함수를 만든다.
            renderPage();	// 페이지네이션 관련 함수를 만든다.
        }
        function renderList() {	// 리스트를 만들어 낼 함수
            var html = '';
            var firstNum = (cp - 1) * listCnt;	// 현재 리스트의 첫번째 
            var lastNum = (cp * listCnt > total) ? total : cp * listCnt;  // 현재 리스트의 마지막

            for(var i = firstNum; i < lastNum; i++) {
                html += '<tr><td>' + obj[i].rank + '</td><td>' + obj[i].name + '</td><td>' + obj[i].total + '</td></tr>';
            }
            $('table > tbody').html(html);
        }
        function renderPage() { // 페이지네이션 부분의 함수
            var phtml = '';
            var block = Math.floor((cp - 1) / pgCnt) + 1; // 보여지는 페이지네이션의 한 묶음을 말한다. console.log로 찍어보면 알겠지만 1,2,3 이 모두 1로 나온다. 4,5,6은 2
            sPage = ((block - 1) * pgCnt) + 1;	// 페이지네이션의 시작 번호
            ePage = (sPage + pgCnt - 1 > totalPage) ? totalPage : sPage + pgCnt - 1; // 페이지네이션의 끝 번호
            if(cp > 1) {
                phtml += '<a href="javascript:void(0);" class="first_page arrow"><<</a>';
            }
            if(block > 1) {
                phtml += '<a href="javascript:void(0);" class="back_page arrow"><</a>';
            }
            for(var i = sPage; i <= ePage; i++) {
                if(cp == i) {
                    phtml += '<a href="javascript:void(0);" class="pg-link on" data-page="' + i + '">' + i + '</a>';
                } else {
                    phtml += '<a href="javascript:void(0);" class="pg-link" data-page="' + i + '">' + i + '</a>';
                }
            }
            if(block < totalBlock) {
                phtml += '<a href="javascript:void(0);" class="next_page arrow">></a>';
            }
            if(cp < totalPage) {
                phtml += '<a href="javascript:void(0);" class="last_page arrow">>></a>';
            }
            $('#pagenav').html(phtml);
            
            if(totalPage <= pgCnt) {
                $('.next_page, .last_page').hide();
            }
        }
        function addEvent() { // 이벤트 발생들을 담은 함수
            $(document).on('click', '#pagenav a', function() {
                if($(this).hasClass('first_page')) {
                    cp = 1;
                } else if ($(this).hasClass('back_page')) {
                    cp = sPage - 1;
                } else if ($(this).hasClass('pg-link')) {
                    cp = $(this).attr('data-page');
                } else if ($(this).hasClass('next_page')) {
                    cp = ePage + 1;
                } else if ($(this).hasClass('last_page')) {
                    cp = totalPage;
                }
                renderTable();
            });
            $(document).on('change', '#data-per-page', function() {
                listCnt = $(this).val();
                totalPage = Math.ceil(total/listCnt);
                if(totalPage <= pgCnt) {
                    cp = 1;
                }
                renderTable();
            });
        }
        renderTable();
        addEvent()
    }
    ranking();
});

 

우선 for문 연습겸 나중에 유동적이게 하기 위해 select부분의 option을 for문을 돌렸다.

나머지는 게시판과 페이지네이션을 만들기 위한 스크립트이다.

복잡할 수 있고 길어보이지만 막상 계속 반복해서 작성해보니 그리 길게 느껴지진 않았다.

 

혹시 아직 이해는 안되지만 해보고싶다면 그냥 태그를 다 복사해서

실행해보고 console.log로 변수들 값을 찍어보면서 계속 반복하면서 해보면 게시판도 혼자 만들게 되는 능력을 얻고

스크립트의 이해도가 조금이나마 올라가게 될것이다.

 

 

728x90
반응형

댓글