웹 애플리케이션 개발 시, 사용자가 데이터를 조회하거나 필터링할 수 있는 인터페이스를 제공하는 것은 매우 중요합니다. 이번 글에서는 Bootstrap을 활용해 탭 방식의 다이얼로그를 구현하는 방법을 살펴보겠습니다.
주요 기능 설명
구현할 기능은 다음과 같습니다:
- 탭 기반의 다이얼로그: 두 개의 탭으로 구성된 UI를 통해 사용자가 "API 품목"과 "날짜" 기반 조회 중 하나를 선택할 수 있습니다.
- BootstrapDialog를 활용한 다이얼로그: 다이얼로그 컴포넌트를 사용해 사용자에게 조회 옵션을 제공합니다.
- 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>
주요 포인트
- 탭 UI 구성: Bootstrap의 nav-tabs 클래스를 활용해 직관적인 탭 네비게이션을 구현했습니다.
- 다이얼로그 컴포넌트: BootstrapDialog를 사용하여 다이얼로그를 쉽게 생성하고 사용자 인터페이스를 간결하게 유지했습니다.
- API 연동: 선택한 탭에 따라 적절한 API를 호출하고, 데이터를 받아옵니다.
이 코드를 활용하면 간단한 조회 기능부터 복잡한 데이터 필터링 기능까지 확장 가능합니다. Svelte와 Bootstrap을 조합해 사용자 친화적인 UI를 설계해보세요!