본문 바로가기
JavaScript/과제테스트

[프로그래머스] [2022 Dev-Matching: 웹 프론트엔드 개발자(하반기)-2] 사원 정보 테이블 구축 문제 풀이

by 김춘삼씨의 고양이 2023. 6. 22.

📌 문제

https://school.programmers.co.kr/skill_check_assignments/364

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

📌 풀이

소스코드 디렉터리 구조

 

index.html

<!DOCTYPE html>
<html lang="ko">
    <link rel="stylesheet" href="/web/style.css">
    <head>
        <meta charset="UTF-8">
        <title>2022 Dev-Matching: 웹 프론트엔드 개발자(하반기)-2</title>
    </head>
    <body>
        <div class="App">
            <div id="page_title">Grepp Enterprise</div>
            <div class="area" id="dropdown"></div>
            <div class="area" id="table"></div>
            <div class="area" id="pagination"></div>
        </div>
        <script type="module" src="/web/index.js"></script>
    </body>
</html>

 

index.js

import App from "./src/App.js";

new App(document.querySelector(".App"));

 

App.js

import Table from "./Table.js";
import Pagination from "./Pagination.js";
import Dropdown from "./Dropdown.js";

class App {
    constructor($app) {
        this.$app = $app;
        this.render();
    }

    async render() {
        const response = await fetch("/web/src/data.json");
        const data = await response.json();
        const options = [5, 15];

        new Table(data.slice(0, 5));
        new Pagination(data).render();
        new Dropdown(data, options);
    }
}

export default App;

 

Table.js

class Table {
    constructor(data) {
        this.data = data;
        this.render();
    }

    setTableBody = () => {
        const tbody = document.createElement("tbody");

        for(let i in this.data) {
            const tr = document.createElement("tr");

            for(let j=0; j<4; j++) {
                const td = document.createElement("td");
                td.appendChild(document.createTextNode(Object.values(this.data[i])[j]));
                tr.appendChild(td);
            }

            tbody.appendChild(tr);
        }

        return tbody;
    }

    render() {
        const table = document.createElement("table");
        const thead = document.createElement("thead");
        const theadTr = document.createElement("tr");

        for(let i=0; i<4; i++) {
            const th = document.createElement("th");
            th.appendChild(document.createTextNode(Object.keys(this.data[0])[i]));
            theadTr.appendChild(th);
        }

        thead.appendChild(theadTr);
        table.appendChild(thead);
        table.appendChild(this.setTableBody());

        document.getElementById("table").appendChild(table);
    }
}

export default Table;

 

Pagination.js

import Table from "./Table.js";

class Pagination {
    constructor(data) {
        this.data = data;
    }

    changeBtnStyle = (prevPage, currentPage) => {
        const pagination = document.getElementById("pagination");

        pagination.children[prevPage].removeAttribute("class", "active");
        pagination.children[currentPage].setAttribute("class", "active");
    }

    onBtnClick = (elemsPerPage, currentPage, prevPage) => {
        document.getElementById("table").innerHTML = "";

        let start = elemsPerPage * (currentPage-1);
        let end = start + elemsPerPage;

        new Table(this.data.slice(start, end));

        if(prevPage !== currentPage) {
            this.changeBtnStyle(prevPage, currentPage);
        }
    }

    setPaginationBtns = (elemsPerPage, currentPage, maxPageCnt) => {
        for(let i=0; i<maxPageCnt; i++) {
            const button = document.createElement("button");

            if(i === 0) {
                button.setAttribute("class", "arrow");
                button.appendChild(document.createTextNode("<<"));
            } else if (i === maxPageCnt-1) {
                button.setAttribute("class", "arrow");
                button.appendChild(document.createTextNode(">>"));
            } else {
                button.appendChild(document.createTextNode(i));
            }

            button.addEventListener("click", () => {
                let prevPage = currentPage;

                if(i === 0) {
                    currentPage = 1;
                } else if (i === maxPageCnt-1) {
                    currentPage = maxPageCnt-2;
                } else {
                    currentPage = i;
                }

                this.onBtnClick(elemsPerPage, currentPage, prevPage);
            });

            document.getElementById("pagination").appendChild(button);
        }
        
        document.getElementById("pagination").children[currentPage].setAttribute("class", "active");
    }

    render() {
        let elemsPerPage = 5;
        let currentPage = 1;
        let maxPageCnt = (this.data.length%elemsPerPage === 0) ? parseInt(this.data.length/elemsPerPage)+2 : parseInt(this.data.length/elemsPerPage)+3;

        this.setPaginationBtns(elemsPerPage, currentPage, maxPageCnt);
    }
}

export default Pagination;

 

Dropdown.js

import Table from "./Table.js";
import Pagination from "./Pagination.js";

class Dropdown {
    constructor(data, options) {
        this.data = data;
        this.options = options;
        this.render();
    }

    render() {
        const select = document.createElement("select");

        for(let i in this.options) {
            const option = document.createElement("option");
            option.setAttribute("value", this.options[i]);
            option.appendChild(document.createTextNode(`${this.options[i]}개씩`));

            select.appendChild(option);
        }

        select.addEventListener("change", (event) => {
            let elemsPerPage = parseInt(event.target.value);
            let currentPage = 1;
            let maxPageCnt = (this.data.length%elemsPerPage === 0) ? parseInt(this.data.length/elemsPerPage)+2 : parseInt(this.data.length/elemsPerPage)+3;

            document.getElementById("table").innerHTML = "";
            document.getElementById("pagination").innerHTML = "";

            new Table(this.data.slice(0, elemsPerPage));
            new Pagination(this.data).setPaginationBtns(elemsPerPage,currentPage, maxPageCnt);
        })

        document.getElementById("dropdown").appendChild(select);
    }
}

export default Dropdown;

 

style.css

body {
    padding: 50px 50px;
    background-color: #f2f2f2;
}

#page_title {
    margin: 20px 0;
    font-size: 1.5rem;
    font-weight: bold;
}

table {
    border-collapse: collapse;
    width: 100%;
    background-color: white;
    text-align: center;
}

thead {
    background-color: lightgray;
    font-weight: bold;
}

th, td {
    border: 1px solid #dddddd;
    padding: 8px;
}

tr:nth-child(even) {
    background-color: lightgray;
}

.area {
    margin: 10px 0;
}

#dropdown {
    display: flex;
    justify-content: flex-end;
}

#table {
    padding: 10px 0;
    font-size: 1.0rem;
}

#pagination {
    padding: 10px 10px;
    text-align: center;
    background-color: white;
}

#pagination > button {
    margin: 0 10px;
    font-size: 1.0rem;
    font-weight: 550;
    border: 0;
    background-color: white;
    cursor: pointer;
}

button.arrow {
    color:red;
}

button.active {
    color: red;
}

 

📌 실행 결과

 

 

댓글