Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- jsp
- icon
- 스파르타코딩클럽
- 이클립스
- SQL
- 티스토리챌린지
- CSS
- 코딩
- Firebase
- java
- 기업설명회
- 오블완
- error
- 웹개발
- 자바
- JavaScript
- Eclipse
- 오류
- myBatis
- 깃허브
- vscode
- jQuery
- SQLD
- HTML
- ChatGPT
- AJAX
- github
- spring
- restapi
- bootstrap
Archives
- Today
- Total
푸들푸들
[Error] 탭 변경 시 CSS 깨짐 본문
저번 글과 이어서..
<div class="simple-tab">
<!-- 탭 title -->
<ul class="nav nav-tabs d-flex justify-content-between" id="pills-tab" role="tablist">
<div class="d-flex">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="전체-tab" data-bs-toggle="tab" data-bs-target="#전체-tab-pane" type="button" role="tab" aria-controls="#전체-tab-pane" aria-selected="true">전체</button>
</li>
<c:forEach var="ct" items="${categoryList}">
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab${ct.catNo}" data-bs-toggle="tab" data-bs-target="#${ct.catName}-tab-pane" type="button" role="tab" aria-controls="#${ct.catName}-tab-pane" aria-selected="false">${ct.catName}</button>
</li>
</c:forEach>
</div>
<span style="text-align: right;">
<a class="btn btn-secondary" id="insertBoard" href="${pageContext.request.contextPath}/board/insert">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus">
<line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg> 글쓰기
</a>
</span>
</ul>
<!-- END 탭 title -->
<div class="tab-content" id="tabContent">
<!-- 탭1 - 전체 -->
<div class="tab-pane fade show active" id="전체-tab-pane" role="tabpanel" aria-labelledby="전체-tab" tabindex="0">
<div class="widget-content widget-content-area br-8">
<table id="board-list" class="table dt-table-hover" style="width:100%">
<thead>
<tr>
<th style="text-align: center;">번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th style="text-align: center;">조회수</th>
<th style="text-align: center;">추천</th>
</tr>
</thead>
<tbody>
<c:forEach var="b" items="${boardList}">
<tr>
<td style="text-align: center;">${b.boaNo}</td>
<td>
<div class="d-flex justify-content-left align-items-center">
<div class="d-flex flex-column">
<span class="text-truncate fw-bold">
[${b.catName}] <a href="${pageContext.request.contextPath}/board/${b.boaNo}">${b.title}</a>
</span>
</div>
</div>
</td>
<td>${b.ename}</td>
<td>${b.createDate}</td>
<td style="text-align: center;">${b.viewCnt}</td>
<td style="text-align: center;">${b.countLike}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<!-- END 탭1 - 전체 -->
<!-- 탭2 - 인기글 --> <!-- 추천수 10개 이상 -->
<!-- 탭3 ~ -->
<c:forEach var="ct" items="${categoryList}">
<c:if test="${ct.catNo != 1}"> <!-- 공지(catNo=1) 제외 -->
<div class="tab-pane fade" id="${ct.catName}-tab-pane" role="tabpanel" aria-labelledby="tab${ct.catNo}" tabindex="0">
<div class="widget-content widget-content-area br-8">
<table id="${ct.catName}-board-list" class="table dt-table-hover" style="width:100%">
<thead>
<tr>
<th style="text-align: center;">번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th style="text-align: center;">조회수</th>
<th style="text-align: center;">추천</th>
</tr>
</thead>
<tbody>
<!-- ajax -->
</tbody>
</table>
</div>
</div>
</c:if>
</c:forEach>
<!-- END 탭 -->
</div>
</div>
<script src="../src/plugins/src/table/datatable/datatables.js"></script>
<script>
$('#board-list').DataTable({
"dom": "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'f>>>" +
"<'table-responsive'tr>" +
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
"oLanguage": {
"oPaginate": { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>', "sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
"sInfo": "Showing page _PAGE_ of _PAGES_",
"sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
"sSearchPlaceholder": "Search...",
"sLengthMenu": "Results : _MENU_",
},
"stripeClasses": [],
"lengthMenu": [7, 10, 20, 50],
"pageLength": 10
});
</script>
<!-- END PAGE LEVEL SCRIPTS -->
<script>
$(document).ready(function() {
// 기본적으로 전체 탭의 데이터를 로드
tabData('전체');
// 탭 클릭 이벤트
$('#pills-tab button[data-bs-toggle="tab"]').click(function() {
let buttonId = $(this).attr('id'); // 현재 클릭된 버튼의 ID
let tabDataType;
// tabDataType을 설정
if (buttonId === '전체-tab') {
tabDataType = '전체';
} else {
tabDataType = buttonId.replace('tab', ''); // tabDataType을 버튼 ID에서 'tab'을 제거한 값으로 설정
}
// 해당 탭의 데이터를 로드
tabData(tabDataType);
});
function tabData(tabData) {
let url;
if (tabData === '전체') {
url = '/board';
} else {
let catNo = tabData.replace('tab', '').trim();
console.log(catNo);
url = `/board/byCategory/`+catNo; // 카테고리별 게시글을 가져오는 URL
console.log(url);
}
fetch(url)
.then(response => response.json())
.then(data => {
let tbody;
if (tabData === '전체') {
tbody = $('#board-list tbody'); // 전체 탭의 tbody
} else {
tbody = $(`#${tabData}-board-list tbody`); // 카테고리 탭의 tbody
}
tbody.empty(); // 기존 데이터 초기화
data.forEach(item => {
console.log(item)
let row = $('<tr></tr>');
row.append($('<td></td>').text(item.boaNo));
row.append($('<td></td>').html(`[${item.catName}] <a href="/board/${item.boaNo}">${item.title}</a>`));
row.append($('<td></td>').text(item.ename));
row.append($('<td></td>').text(item.createDate));
row.append($('<td></td>').text(item.viewCnt));
row.append($('<td></td>').text(item.countLike));
tbody.append(row); // 새로운 행 추가
});
})
.catch(error => console.error('Error loading data:', error));
}
});
</script>
처음 화면인 '전체' 탭은 괜찮은데
다른 탭을 선택하면 css가 깨져서 나타남
-> 페이지네이션, 검색 등을 추가하는 부분을 탭이 바뀔 때마다 초기화 했다가 다시 추가하는 방식으로 구현해보자!
<div class="tab-content" id="tabContent">
<!-- 탭1 - 전체 -->
<div class="tab-pane fade show active" id="전체-tab-pane" role="tabpanel" aria-labelledby="tab-전제" tabindex="0">
<div class="widget-content widget-content-area br-8">
<table id="board-list" class="table dt-table-hover zero-config" style="width: 100%">
<thead>
<tr>
<th style="text-align: center;">번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th style="text-align: center;">조회수</th>
<th style="text-align: center;">추천</th>
</tr>
</thead>
<tbody>
<c:forEach var="b" items="${boardList}">
<tr>
<td style="text-align: center;">${b.boaNo}</td>
<td>
<div class="d-flex justify-content-left align-items-center">
<div class="d-flex flex-column">
<span class="text-truncate fw-bold">
[${b.catName}] <a href="${pageContext.request.contextPath}/board/${b.boaNo}">${b.title}</a>
</span>
</div>
</div>
</td>
<td>${b.ename}</td>
<td>${b.createDate}</td>
<td style="text-align: center;">${b.viewCnt}</td>
<td style="text-align: center;">${b.countLike}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
<!-- END 탭1 - 전체 -->
<!-- 탭2 - 인기글 -->
<!-- 추천수 10개 이상 -->
<!-- 탭3 ~ -->
<c:forEach var="ct" items="${categoryList}">
<c:if test="${ct.catNo != 1}">
<!-- 공지(catNo=1) 제외 -->
<div class="tab-pane fade show" id="${ct.catNo}-tab-pane" role="tabpanel" aria-labelledby="tab-${ct.catNo}" tabindex="0">
<div class="widget-content widget-content-area br-8">
<table id="${ct.catNo}-board-list" class="table dt-table-hover zero-config" style="width: 100%">
<thead>
<tr>
<th style="text-align: center;">번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
<th style="text-align: center;">조회수</th>
<th style="text-align: center;">추천</th>
</tr>
</thead>
<tbody>
<!-- ajax -->
</tbody>
</table>
</div>
</div>
</c:if>
</c:forEach>
<!-- END 탭 -->
</div>
모든 table에 적용하기 위해 class="zero-config"를 추가하여 호출
<!-- zero-config 적용/삭제 하는 함수 -->
<script>
function initDataTable() {
$('.zero-config').DataTable({
"dom": "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'f>>>" +
"<'table-responsive'tr>" +
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
"oLanguage": {
"oPaginate": { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>',
"sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
"sInfo": "Showing page _PAGE_ of _PAGES_",
"sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
"sSearchPlaceholder": "Search...",
"sLengthMenu": "Results : _MENU_",
},
"stripeClasses": [],
"lengthMenu": [7, 10, 20, 50],
"pageLength": 10
});
}
function destroyDataTable() {
$('.zero-config').DataTable().destroy();
}
</script>
적용, 삭제를 용이하게 하기위해 함수 생성
<script>
$(document).ready(function() {
// 기본적으로 전체 탭의 데이터를 로드
tabData('전체');
initDataTable();
// 탭 클릭 이벤트
$('#pills-tab button[data-bs-toggle="tab"]').click(function() {
let buttonId = $(this).attr('id'); // 현재 클릭된 버튼의 ID
let tabDataType;
// tabDataType을 설정
if (buttonId === 'tab-전체') {
tabDataType = '전체';
} else {
tabDataType = buttonId.replace('tab-', ''); // tabDataType을 버튼 ID에서 'tab-'을 제거한 값 = catNo
}
tabData(tabDataType); // 해당 탭의 데이터를 로드
});
function tabData(tabData) {
let url;
if (tabData === '전체') {
url = '/board';
} else {
let catNo = tabData.replace('tab', '').trim();
console.log(catNo);
url = `/board/byCategory/`+catNo; // 카테고리별 게시글을 가져오는 URL
console.log(url);
}
$.ajax({
method: 'GET',
url: url,
success: function (data) {
console.log(data);
destroyDataTable(); // 이전 DataTable 인스턴스 삭제
let tableId = tabData === '전체' ? 'board-list' : tabData + '-board-list'; // 테이블 ID 선택 = catNo-board-list
console.log(tableId);
let table = $('#' + tableId).DataTable({ // 새로운 DataTable 인스턴스 생성
paging: true,
destroy: true, // 기존 데이터를 파괴하고 새로 초기화
"dom": "<'dt--top-section'<'row'<'col-12 col-sm-6 d-flex justify-content-sm-start justify-content-center'l><'col-12 col-sm-6 d-flex justify-content-sm-end justify-content-center mt-sm-0 mt-3'f>>>" +
"<'table-responsive'tr>" +
"<'dt--bottom-section d-sm-flex justify-content-sm-between text-center'<'dt--pages-count mb-sm-0 mb-3'i><'dt--pagination'p>>",
"oLanguage": {
"oPaginate": { "sPrevious": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>',
"sNext": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>' },
"sInfo": "Showing page _PAGE_ of _PAGES_",
"sSearch": '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
"sSearchPlaceholder": "Search...",
"sLengthMenu": "Results : _MENU_",
},
"stripeClasses": [],
"lengthMenu": [7, 10, 20, 50],
"pageLength": 10
});
// 데이터 추가
data.forEach(item => {
// console.log(item);
let rowDate = [
item.boaNo,
`[\${item.catName}] <a href="/board/\${item.boaNo}">\${item.title}</a>`,
item.ename,
new Date(item.createDate).toLocaleString(), // 날짜 형식 변환
item.viewCnt,
item.countLike
];
table.row.add(rowDate);
});
// console.log(data.length);
table.draw(); // 테이블 업데이트
},
error: function (xhr, status, error) {
console.error(`Error: ${status}, ${error}`);
}
});
}
});
</script>
ajax 호출 성공 시 인스턴스를 삭제하고 추가하도록 구현
해결..?
아직 약간 부족..
'구디아카데미 > Error' 카테고리의 다른 글
[Error] 모달 fetch 404 (0) | 2025.01.23 |
---|---|
[Error] Jsp <script> ${} 오류 (1) | 2025.01.14 |
[Error] 400 오류 - Spring Security (0) | 2025.01.13 |
[Error] 500 오류 (0) | 2024.11.14 |
[Error] 400 오류 / 검색 기능 (0) | 2024.11.13 |