본문 바로가기

JavaScript

[자바스크립트 예제 #03] filter() 필터 메뉴 만들기

 

바닐라 자바스크립트 예제 filter 함수


소개 및 자바스크립트 개념

메뉴를 필터링해주는 페이지. 

- 배열, 객체

- forEach()

- DOM : DOMContentLoaded

- map, reduce, filter

- innerHTML

- includes()

 

app. js

1. menu 배열 및 보여줄 항목들에 대한 부모요소 선택

- menu는 객체 배열로 바뀔 부분에 대한 데이터가 키:값 구성으로 되어있다.

- .btns-wrap과 .items-wrap을 querySelector로 선택

// items
const menu = [
  {
    id: 1,
    title: "buttermilk pancakes",
    category: "breakfast",
    price: 15.99,
  },
  {
    id: 2,
    title: "diner double",
    category: "lunch",
    price: 13.99,
  },
  {
    id: 3,
    title: "country delight",
    category: "breakfast",
    price: 20.99,
  },
  {
    id: 4,
    title: "egg attack",
    category: "lunch",
    price: 22.99,
  },
  {
    id: 5,
    title: "bacon overflow",
    category: "breakfast",
    price: 8.99,
  },
  {
    id: 6,
    title: "american classic",
    category: "lunch",
    price: 12.99,
  },
  {
    id: 7,
    title: "steak dinner",
    category: "dinner",
    price: 39.99,
  },
];

const itemsWrap = document.querySelector(".items-wrap");
const btnsWrap = document.querySelector(".btns-wrap");

 

2. 메뉴를 보여주는 함수 showMenuItems()

- map()함수로 menu  객체 배열의 title과 price 키에 접근하여 값을 가져온다. menu.title과 menu.price로 값을 이용하여 .menu-item HTML 요소 문자열로 리턴해준다.

- HTML 요소 문자열로 리턴받은 join("")함수를 사용해서 여러개의 <div class="menu-item">..</div> 를 만든다.

-.items-wrap에 위의 문자열을 HTML 요소로 넣는다.

function showMenuItems(menuItems) {
  let showMenu = menuItems.map(function (item) {
    return `<div class="menu-item"><p>${item.title}</p><strong class="price">$${item.price}</strong></div>`;
  });

  showMenu = showMenu.join("");
  itemsWrap.innerHTML = showMenu;
}

 

3. 버튼에 따라 내용이 바뀌는 함수

- menu 배열에서 category 키값만으로 새로운 배열을 만들어서, categories 상수에 담는다. cateogry 배열의 초기값은 "all"이다.

- 그렇게 만든 cateogries 배열에서 각각의 원소에 .btn-filter HTML 요소안에 값을 넣어서 새 배열을 만든다. 이 새 배열들을 문자열로 합쳐(join)서 여러개의 button 태그를 만든다.(innerHTML)

- 만들어진 .btn-filter에 click 이벤트로 콜백함수를 실행한다.

- 이 콜백함수 구문에서는 filter() 메소드를 사용하는데, filter는 콜백 함수에 만족하는 모든 요소를 모아 새 배열로 반환한다.

- 즉, menu 배열에서의 category 속성의 값과 button.btn-filter의 data-id 속성이 일치하면 menu 배열중, 그 원소를 리턴한다. 

- 만일 button.btn-filter의 data-id 속성이 "all" 이라면, showMenuItems에 menu 배열을 넣어서 모두 보여줌,

그렇지 않다면 menu 배열중, 그 원소를 넣어서(menuCategory) 보여줌

function showMenuBtns() {
  const categories = menu.reduce(
    function (values, item) {
      if (!values.includes(item.category)) {
        values.push(item.category);
      }
      return values;
    },
    ["all"]
  );
  
  const categoryBtns = categories
    .map((category) => {
      return `<button type="button" class="btn-filter" data-id=${category}>${category}</button>`;
    })
    .join("");
  btnsWrap.innerHTML = categoryBtns;

  const filterBtns = btnsWrap.querySelectorAll(".btn-filter");
  console.log(filterBtns);

  filterBtns.forEach(function (btn) {
    btn.addEventListener("click", function (e) {
      const category = e.currentTarget.dataset.id;
      const menuCategory = menu.filter(function (menuItem) {
        if (menuItem.category === category) {
          return menuItem;
        }
      });
      if (category === "all") {
        showMenuItems(menu);
      } else {
        showMenuItems(menuCategory);
      }
    });
  });
 }

 

4. 화면 로드시 실행되도록
window.addEventListener("DOMContentLoaded", function () {
  showMenuItems(menu);
  showMenuBtns();
});

 

HTML, CSS, JS 모든 소스보기

- https://github.com/SSOHERB/BasicJavaScript/tree/master/BasicJavaScript/MenuFilter

 

출처

- https://github.com/john-smilga/javascript-basic-projects