Adventure Time - Finn 3
본문 바로가기
카테고리 없음

Bootstrap을 활용한 다이얼로그 탭

by hyun9_9 2025. 1. 27.

웹 애플리케이션 개발 시, 사용자가 데이터를 조회하거나 필터링할 수 있는 인터페이스를 제공하는 것은 매우 중요합니다. 이번 글에서는 Bootstrap을 활용해 탭 방식의 다이얼로그를 구현하는 방법을 살펴보겠습니다.


주요 기능 설명

구현할 기능은 다음과 같습니다:

  1. 탭 기반의 다이얼로그: 두 개의 탭으로 구성된 UI를 통해 사용자가 "API 품목"과 "날짜" 기반 조회 중 하나를 선택할 수 있습니다.
  2. BootstrapDialog를 활용한 다이얼로그: 다이얼로그 컴포넌트를 사용해 사용자에게 조회 옵션을 제공합니다.
  3. API 연동: 선택한 옵션에 따라 적절한 API를 호출합니다.

구현 코드

Svelte 컴포넌트 코드

아래는 전체 코드입니다. 필요에 따라 수정하거나 재사용할 수 있습니다.

<script>
  import 'bootstrap/dist/css/bootstrap.min.css';
  import api from "/src/lib/api.js";
  import { createEventDispatcher } from 'svelte';
  let activeTab = 'api'; // 기본 탭은 'api'
  let startDate = '';    // 시작 날짜
  let endDate = '';      // 종료 날짜
  const dispatch = createEventDispatcher();

  // 탭 변경 함수
  const setTab = (tab) => {
    activeTab = tab;
    document.querySelectorAll('.nav-link').forEach((tabLink) => {
      if (tabLink.innerText === 'API 품목' && tab === 'api') {
        tabLink.classList.add('active');
      } else if (tabLink.innerText === 'API 품목') {
        tabLink.classList.remove('active');
      }
      if (tabLink.innerText === '날짜' && tab === 'date') {
        tabLink.classList.add('active');
      } else if (tabLink.innerText === '날짜') {
        tabLink.classList.remove('active');
      }
    });

    document.querySelectorAll('.tab-content').forEach((content) => {
      if (content.classList.contains(tab)) {
        content.style.display = 'block';
      } else {
        content.style.display = 'none';
      }
    });
  };

  const showDialog = () => {
    const content = document.createElement('div');

    // 탭 네비게이션 생성
    const nav = document.createElement('ul');
    nav.className = 'nav nav-tabs';
    const tabs = [
      { id: 'api', label: 'API 품목' },
      { id: 'date', label: '날짜' },
    ];

    tabs.forEach((tab) => {
      const tabItem = document.createElement('li');
      tabItem.className = 'nav-item';

      const tabLink = document.createElement('a');
      tabLink.className = `nav-link ${activeTab === tab.id ? 'active' : ''}`;
      tabLink.href = '#';
      tabLink.innerText = tab.label;
      tabLink.addEventListener('click', (event) => {
        event.preventDefault();
        setTab(tab.id);
      });

      tabItem.appendChild(tabLink);
      nav.appendChild(tabItem);
    });

    content.appendChild(nav);

    // 탭 내용 생성
    const apiTabContent = document.createElement('div');
    apiTabContent.className = `tab-content mt-3 api ${activeTab === 'api' ? 'active' : ''}`;
    apiTabContent.style.display = activeTab === 'api' ? 'block' : 'none';
    apiTabContent.innerText = '조회합니다.';

    const dateTabContent = document.createElement('div');
    dateTabContent.className = `tab-content mt-3 date`;
    dateTabContent.style.display = activeTab === 'date' ? 'block' : 'none';

    const mainText = document.createElement('p');
    mainText.innerText = '날짜를 기준으로 조회합니다.';
    dateTabContent.appendChild(mainText);

    const subText = document.createElement('p');
    subText.style.color = 'red';
    subText.style.fontSize = '0.7rem';
    subText.style.marginTop = '0.5rem';
    dateTabContent.appendChild(subText);

    const startDateDiv = document.createElement('div');
    startDateDiv.className = 'mb-3';
    const startLabel = document.createElement('label');
    startLabel.setAttribute('for', 'startDate');
    startLabel.className = 'form-label';
    startLabel.innerText = '시작 날짜';
    const startInput = document.createElement('input');
    startInput.type = 'date';
    startInput.id = 'startDate';
    startInput.className = 'form-control';
    startInput.value = startDate;
    startInput.addEventListener('change', (e) => {
      startDate = e.target.value;
    });
    startDateDiv.appendChild(startLabel);
    startDateDiv.appendChild(startInput);

    const endDateDiv = document.createElement('div');
    endDateDiv.className = 'mb-3';
    const endLabel = document.createElement('label');
    endLabel.setAttribute('for', 'endDate');
    endLabel.className = 'form-label';
    endLabel.innerText = '종료 날짜';
    const endInput = document.createElement('input');
    endInput.type = 'date';
    endInput.id = 'endDate';
    endInput.className = 'form-control';
    endInput.value = endDate;
    endInput.addEventListener('change', (e) => {
      endDate = e.target.value;
    });
    endDateDiv.appendChild(endLabel);
    endDateDiv.appendChild(endInput);

    dateTabContent.appendChild(startDateDiv);
    dateTabContent.appendChild(endDateDiv);

    content.appendChild(apiTabContent);
    content.appendChild(dateTabContent);

    let data = null;

    BootstrapDialog.show({
      title: '조회',
      message: content,
      type: BootstrapDialog.TYPE_DEFAULT,
      buttons: [
        {
          label: '취소',
          cssClass: 'btn-outline-secondary',
          action(dialog) {
            dialog.close();
          },
        },
        {
          label: '조회하기',
          cssClass: 'btn-outline-primary',
          async action(dialog) {
            if (activeTab === 'api') {
              alert('번호로 조회합니다.');
              
            } else if (activeTab === 'date') {
              if (!startDate || !endDate) {
                alert('날짜를 모두 선택해주세요.');
                return;
              }
              alert(`날짜를 기준으로 조회합니다: ${startDate} - ${endDate}`);
              
            }
            
            dialog.close();
          },
        },
      ],
    });
  };
</script>

<button class="btn-grid-primary" on:click={showDialog} data-html="true" data-toggle="tooltip" data-trigger="hover" title="API조회">wms API조회</button>

주요 포인트

  1. 탭 UI 구성: Bootstrap의 nav-tabs 클래스를 활용해 직관적인 탭 네비게이션을 구현했습니다.
  2. 다이얼로그 컴포넌트: BootstrapDialog를 사용하여 다이얼로그를 쉽게 생성하고 사용자 인터페이스를 간결하게 유지했습니다.
  3. API 연동: 선택한 탭에 따라 적절한 API를 호출하고, 데이터를 받아옵니다.

이 코드를 활용하면 간단한 조회 기능부터 복잡한 데이터 필터링 기능까지 확장 가능합니다. Svelte와 Bootstrap을 조합해 사용자 친화적인 UI를 설계해보세요!