본문 바로가기
etc/[프로그래머스] 데브매칭

[프로그래머스/2022 하반기 프론트엔드 데브매칭] 사원 정보 테이블 구축 답안코드 + 코드 분석

by 1two13 2023. 3. 3.
728x90
반응형

문제 


프로그래머스 > 코딩 테스트 연습 > 과제 테스트 연습 > 프로그래밍 언어 검색

index.html부터 코드 흐름을 읽어나가면 됩니다!

728x90

 

 

 

 

답변 코드


// index.html

<!DOCTYPE html>
<html lang="ko">
  <link rel="stylesheet" href="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">
        <!-- <button class="arrow"><<</button>
        <button style="color: red">1</button>
        <button>2</button>
        <button>3</button>
        <button>4</button>
        <button>5</button>
        <button class="arrow">>></button> -->
      </div>
    </div>
    <script type="module" src="index.js"></script>
  </body>
</html>

 

// index.js
import App from './App.js';

new App(document.querySelector('.App')).render();

 

// App.js

import Pagination from './src/Pagination.js';
import Table from './src/Table.js';
import Dropdown from './src/Dropdown.js';

class App {
  async render() {
    const response = await fetch('./src/data.json');

    if (response.ok) {
      const fetchedData = await response.json();
      // 첫 화면에서 table 5개 보여주기
      new Table(fetchedData.slice(0, 5));
      new Pagination(fetchedData).render();
      new Dropdown(fetchedData, [5, 15]);
    }
  }
}

export default App;
반응형

 

// src/Table.js

class Table {
  #data;

  constructor(data) {
    this.#data = data;
    this.render();
  }

  render() {
    const table = document.createElement('table');
    // 모든 자식 노드 비우기
    table.replaceChildren();
    const thead = this.displayTableHead();
    const tbody = document.createElement('tbody');

    for (let i = 0; i < this.#data.length; i++) {
      let tbodyTr = this.displayTableData(this.#data[i]);
      tbody.appendChild(tbodyTr);
    }

    table.appendChild(tbody);
    table.appendChild(thead);
    document.getElementById('table').appendChild(table);
  }

  displayTableHead = () => {
    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);
    return thead;
  };

  displayTableData = (data) => {
    const tr = document.createElement('tr');

    for (let i = 0; i < 4; i++) {
      const td = document.createElement('td');

      td.appendChild(document.createTextNode(Object.values(data)[i]));
      tr.appendChild(td);
    }

    return tr;
  };
}

export default Table;

 

// src/Pagination.js

import Table from './Table.js';

class Pagination {
  #data;

  constructor(data) {
    this.#data = data;
  }

  render() {
    // 버튼의 개수
    let maxPageCnt = 7;
    // 현재 페이지 번호
    let currentPage = 1;

    this.setPaginationButtons(maxPageCnt, currentPage);
  }

  setPaginationButtons = (maxPageCnt, currentPage) => {
    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 === 1) {
        button.setAttribute('class', 'active');
        button.appendChild(document.createTextNode(i));
      } else if (i === maxPageCnt - 1) {
        button.setAttribute('class', 'arrow');
        button.appendChild(document.createTextNode('>>'));
      } else button.appendChild(document.createTextNode(i));

      document.getElementById('pagination').appendChild(button);
      button.addEventListener('click', () => {
        if (i === 0) currentPage = 1;
        else if (i === maxPageCnt - 1) currentPage = maxPageCnt - 2;
        else currentPage = i;

        this.paginationButtonClicked(
          maxPageCnt,
          currentPage,
          document.getElementById('pagination').children
        );
      });
    }
  };

  paginationButtonClicked = (maxPageCnt, currentPage, button) => {
    let end;
    let start;
    if (maxPageCnt === 4) {
      end = currentPage * 15;
      start = end - 15;
    } else if (maxPageCnt === 7) {
      end = currentPage * 5;
      start = end - 5;
    }

    // 버튼 클릭할 때마다 table 초기화
    document.getElementById('table').innerHTML = '';
    this.paginationButtonsStyle(maxPageCnt, currentPage, button);
    this.sliceData(start, end);
  };

  paginationButtonsStyle = (maxPageCnt, currentPage, button) => {
    for (let i = 0; i < maxPageCnt; i++) {
      if (currentPage === i) {
        button[i].classList.add('active');
      } else button[i].classList.remove('active');
    }
  };

  sliceData(start, end) {
    new Table(this.#data.slice(start, end));
  }
}

export default Pagination;

 

// src/Dropdown.js

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

class Dropdown {
  #data;
  #options;

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

  render() {
    const select = document.createElement('select');
    select.setAttribute('id', 'cntPerPage');

    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);
    }

    document.getElementById('dropdown').appendChild(select);
    select.addEventListener('change', (event) => {
      let pagePerCnt = Number(event.target.value);
      let maxPageCnt = pagePerCnt === 15 ? 4 : 7;
      let currentPage = 1;

      // select 클릭할 때마다 pagination과 table 초기화
      document.getElementById('pagination').innerHTML = '';
      document.getElementById('table').innerHTML = '';
      // 새로운 데이터 화면에 그리기
      new Table(this.#data.slice(0, pagePerCnt));
      new Pagination(this.#data).setPaginationButtons(maxPageCnt, currentPage);
    });
  }
}

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;
}

th,
td {
  border: 1px solid #dddddd;
  padding: 8px;
  text-align: center;
}

th {
  background-color: lightgray;
}

.area {
  margin: 10px 0;
}

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

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

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

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

button.arrow {
  color: red;
}

button.active {
  color: red;
}

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

 

 

 

 

 


질문이나 잘못된 점은 댓글로 남겨주세요 :)💖

 

 

 

728x90
반응형

댓글