본문 바로가기
HTML/CSS

[HTML/CSS] Tailwind로 검색이 가능한 드롭다운 구현하기

by teamnova 2024. 5. 13.
728x90

안녕하세요 오늘은  Tailwind로 검색이 가능한 드롭다운을 구현해보겠습니다.

 

코드는 다음과 같습니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Advanced Dropdown Menu</title>
    <link href="https://cdn.jsdelivr.net/npm/tailwindcss@3.0.21/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="bg-gray-100 flex justify-center items-center h-screen">
    <div class="relative">
        <!-- 드롭다운 메뉴 버튼 -->
        <button id="dropdownButton" class="bg-blue-500 text-white px-4 py-2 rounded focus:outline-none">메뉴</button>
        <!-- 드롭다운 메뉴 내용, 초기에는 숨겨져 있음 -->
        <div id="dropdownContent" class="hidden absolute w-64 bg-white rounded shadow mt-2">
            <!-- 검색 입력 필드 -->
            <input type="text" placeholder="Search..." id="searchBox" class="w-full px-4 py-2 border-b border-gray-300 focus:outline-none">
            <!-- 메뉴 아이템들을 동적으로 채울 컨테이너 -->
            <div id="menuItems" class="max-h-60 overflow-y-auto">
                <!-- Items are populated by JavaScript -->
            </div>
        </div>
        <!-- 선택된 항목을 표시할 공간 -->
        <div id="selectedItems" class="mt-2 text-blue-800"></div>
    </div>
</body>
<script>
    // 메뉴 아이템 리스트
    const items = ["Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig", "Grape"];
    // DOM 요소 선택
    const dropdownButton = document.getElementById('dropdownButton');
    const dropdownContent = document.getElementById('dropdownContent');
    const searchBox = document.getElementById('searchBox');
    const menuItems = document.getElementById('menuItems');
    const selectedItemsDiv = document.getElementById('selectedItems');
    let selectedItems = [];

    // 메뉴 아이템을 동적으로 생성하고 추가하는 함수
    function populateMenuItems(filter = '') {
        menuItems.innerHTML = ''; // 메뉴 아이템 컨테이너 초기화
        items.filter(item => item.toLowerCase().includes(filter.toLowerCase())).forEach(item => {
            const checkBox = document.createElement('input'); // 체크박스 생성
            checkBox.type = 'checkbox';
            checkBox.checked = selectedItems.includes(item); // 현재 아이템이 선택된 항목 리스트에 있는지 확인
            checkBox.onchange = () => handleSelectionChange(item, checkBox.checked); // 체크박스 상태 변경 이벤트
            const label = document.createElement('label'); // 라벨 요소 생성
            label.textContent = item;
            label.style.display = 'block';
            label.style.margin = '10px';
            label.prepend(checkBox); // 체크박스를 라벨 앞에 추가
            menuItems.appendChild(label); // 라벨을 메뉴 아이템 컨테이너에 추가
        });
    }

    // 선택 상태 변경 처리 함수
    function handleSelectionChange(item, isChecked) {
        if (isChecked) {
            selectedItems.push(item); // 아이템을 선택된 리스트에 추가
        } else {
            selectedItems = selectedItems.filter(selectedItem => selectedItem !== item); // 아이템을 선택된 리스트에서 제거
        }
        selectedItemsDiv.textContent = "Selected: " + selectedItems.join(", "); // 선택된 아이템을 화면에 표시
    }

    // 드롭다운 버튼 클릭 이벤트
    dropdownButton.addEventListener('click', () => {
        dropdownContent.classList.toggle('hidden'); // 드롭다운 내용 토글
        populateMenuItems(); // 메뉴 아이템 채우기
    });

    // 검색 필드 입력 이벤트
    searchBox.addEventListener('input', () => populateMenuItems(searchBox.value));

    // 외부 클릭 이벤트
    window.addEventListener('click', function(e) {
        if (!dropdownButton.contains(e.target) && !dropdownContent.contains(e.target)) {
            dropdownContent.classList.add('hidden'); // 드롭다운 메뉴 숨기기
        }
    });
</script>
</html>

 

 

결과물은 다음과 같습니다.