first commit 2
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
const listBody = document.getElementById('bo_list_body');
|
||||
const toggleBtn = document.getElementById('view-toggle-btn1');
|
||||
const chkAll = document.getElementById('chkall');
|
||||
const loadMoreBtn = document.getElementById('btn-load-more'); // 💡 [추가] 더보기 버튼
|
||||
const pagination = document.querySelector('.bo-pagination'); // 💡 [추가] 페이지네이션
|
||||
|
||||
if (!listBody || !toggleBtn) {
|
||||
return; // 필수 요소가 없으면 스크립트 중단
|
||||
}
|
||||
|
||||
const toggleIcon = toggleBtn.querySelector('i');
|
||||
|
||||
// 초기 뷰 모드는 HTML의 data-view-mode 속성에서 가져옴 (PHP에서 설정됨)
|
||||
let currentViewMode = listBody.dataset.viewMode || 'card';
|
||||
|
||||
// 뷰 모드를 설정하고 버튼의 아이콘과 툴팁을 업데이트하는 함수
|
||||
function setViewMode(mode) {
|
||||
// data-view-mode 속성 변경
|
||||
listBody.dataset.viewMode = mode;
|
||||
|
||||
if (mode === 'card') {
|
||||
// 현재 카드뷰 -> 다음 행동은 '목록형 보기'
|
||||
toggleIcon.className = 'fa fa-bars'; // 목록 아이콘
|
||||
toggleBtn.title = '목록형으로 보기';
|
||||
|
||||
// 💡 [추가] 더보기 버튼 보이기, 페이지네이션 숨기기
|
||||
if (loadMoreBtn) loadMoreBtn.parentElement.style.display = 'block';
|
||||
if (pagination) pagination.style.display = 'none';
|
||||
|
||||
} else { // 'list'
|
||||
// 현재 목록뷰 -> 다음 행동은 '카드형 보기'
|
||||
toggleIcon.className = 'fa fa-th-large'; // 카드 아이콘
|
||||
toggleBtn.title = '카드형으로 보기';
|
||||
|
||||
// 💡 [추가] 더보기 버튼 숨기기, 페이지네이션 보이기
|
||||
if (loadMoreBtn) loadMoreBtn.parentElement.style.display = 'none';
|
||||
if (pagination) pagination.style.display = 'flex';
|
||||
}
|
||||
|
||||
// 쿠키에 저장 (PHP와 연동)
|
||||
set_cookie('board_' + g5_bo_table + '_view_mode', mode, 365);
|
||||
}
|
||||
|
||||
// 토글 버튼 클릭 이벤트
|
||||
toggleBtn.addEventListener('click', function() {
|
||||
// 현재 뷰 모드를 확인하고 반대 모드로 전환
|
||||
const newMode = (listBody.dataset.viewMode === 'card') ? 'list' : 'card';
|
||||
setViewMode(newMode);
|
||||
});
|
||||
|
||||
// 페이지 로드 시 초기 상태 설정
|
||||
setViewMode(currentViewMode);
|
||||
|
||||
// 체크박스 동기화 및 전체 선택 상태 업데이트
|
||||
const listCheckboxes = document.querySelectorAll('input[name="chk_wr_id[]"]');
|
||||
const cardCheckboxes = document.querySelectorAll('input[name="chk_wr_id_card[]"]');
|
||||
|
||||
function updateCheckAllState() {
|
||||
if (!chkAll) return;
|
||||
|
||||
const total = listCheckboxes.length;
|
||||
let checkedCount = 0;
|
||||
|
||||
listCheckboxes.forEach(chk => {
|
||||
if (chk.checked) checkedCount++;
|
||||
});
|
||||
|
||||
chkAll.checked = (total > 0 && total === checkedCount);
|
||||
}
|
||||
|
||||
// 리스트형 체크박스 변경 시
|
||||
listCheckboxes.forEach((listChk, index) => {
|
||||
listChk.addEventListener('change', function() {
|
||||
if (cardCheckboxes[index]) {
|
||||
cardCheckboxes[index].checked = this.checked;
|
||||
}
|
||||
updateCheckAllState();
|
||||
});
|
||||
});
|
||||
|
||||
// 카드형 체크박스 변경 시
|
||||
cardCheckboxes.forEach((cardChk, index) => {
|
||||
cardChk.addEventListener('change', function() {
|
||||
const listChk = document.getElementById('chk_wr_id_' + index);
|
||||
if (listChk) {
|
||||
listChk.checked = this.checked;
|
||||
}
|
||||
updateCheckAllState();
|
||||
});
|
||||
});
|
||||
|
||||
// 전체 선택 체크박스 클릭 시
|
||||
if (chkAll) {
|
||||
chkAll.addEventListener('change', function() {
|
||||
const isChecked = this.checked;
|
||||
listCheckboxes.forEach(chk => chk.checked = isChecked);
|
||||
cardCheckboxes.forEach(chk => chk.checked = isChecked);
|
||||
});
|
||||
}
|
||||
|
||||
// ▼▼▼ [추가] 더보기 버튼 기능 구현 ▼▼▼
|
||||
if (loadMoreBtn) {
|
||||
loadMoreBtn.addEventListener('click', function() {
|
||||
const nextPage = parseInt(this.dataset.page);
|
||||
const originalText = this.textContent;
|
||||
|
||||
this.disabled = true;
|
||||
this.textContent = '로딩 중...';
|
||||
|
||||
// 현재 URL에서 페이지 파라미터만 변경
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set('page', nextPage);
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
|
||||
// 다음 페이지의 카드 아이템들 가져오기
|
||||
const newItems = doc.querySelectorAll('#bo_list_body .bo-card-item');
|
||||
|
||||
if (newItems.length > 0) {
|
||||
newItems.forEach(item => {
|
||||
// 💡 [중요] 새로 가져온 아이템의 체크박스 ID 충돌 방지 및 이벤트 연결 필요
|
||||
// 하지만 여기서는 단순 추가만 하고, 체크박스 기능은 복잡해지므로 생략하거나
|
||||
// 필요하다면 추가 로직 구현해야 함. (일단은 추가만)
|
||||
listBody.appendChild(item);
|
||||
});
|
||||
|
||||
// 다음 페이지 번호 업데이트
|
||||
this.dataset.page = nextPage + 1;
|
||||
this.disabled = false;
|
||||
this.textContent = originalText;
|
||||
|
||||
// 다음 페이지에 더보기 버튼이 없으면 현재 버튼 숨김
|
||||
const nextLoadMoreBtn = doc.getElementById('btn-load-more');
|
||||
if (!nextLoadMoreBtn) {
|
||||
this.parentElement.style.display = 'none';
|
||||
}
|
||||
} else {
|
||||
this.parentElement.style.display = 'none';
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
this.disabled = false;
|
||||
this.textContent = originalText;
|
||||
alert('게시물을 불러오는 중 오류가 발생했습니다.');
|
||||
});
|
||||
});
|
||||
}
|
||||
// ▲▲▲ 여기까지 ▲▲▲
|
||||
|
||||
// 노출 상태 토글 기능
|
||||
$('#bo_list_body').on('click', '.btn-status-toggle', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const button = $(this);
|
||||
const wr_id = button.data('wr-id');
|
||||
const is_on = button.hasClass('status-on');
|
||||
const new_status = is_on ? 'hide' : 'show';
|
||||
const bo_table = $('input[name="bo_table"]').val();
|
||||
|
||||
button.find('i').removeClass('fa-toggle-on fa-toggle-off').addClass('fa-spinner fa-spin');
|
||||
|
||||
$.ajax({
|
||||
url: board_skin_url + '/ajax.status_update.php',
|
||||
type: 'POST',
|
||||
data: {
|
||||
bo_table: bo_table,
|
||||
wr_id: wr_id,
|
||||
status: new_status
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
if (data.success) {
|
||||
button.removeClass('status-on status-off');
|
||||
button.find('i').removeClass('fa-spinner fa-spin');
|
||||
|
||||
if (data.new_status === 'hidden') {
|
||||
button.addClass('status-off').attr('title', '노출 상태로 변경');
|
||||
button.find('i').addClass('fa-toggle-off');
|
||||
} else {
|
||||
button.addClass('status-on').attr('title', '숨김 상태로 변경');
|
||||
button.find('i').addClass('fa-toggle-on');
|
||||
}
|
||||
location.reload();
|
||||
} else {
|
||||
alert(data.error || '상태 변경에 실패했습니다.');
|
||||
button.find('i').removeClass('fa-spinner fa-spin').addClass(is_on ? 'fa-toggle-on' : 'fa-toggle-off');
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
alert('서버와 통신 중 오류가 발생했습니다.');
|
||||
button.find('i').removeClass('fa-spinner fa-spin').addClass(is_on ? 'fa-toggle-on' : 'fa-toggle-off');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* notice :: script.js
|
||||
*/
|
||||
|
||||
jQuery(function($) {
|
||||
// 더보기 버튼 (필요시 구현)
|
||||
$('#btn-load-more').on('click', function() {
|
||||
var page = $(this).data('page');
|
||||
// AJAX 로드 로직 구현
|
||||
console.log('Load more page: ' + page);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
// jQuery가 로드된 후 이 스크립트가 실행되어야 합니다.
|
||||
$(function() {
|
||||
// Datepicker 초기화
|
||||
$(".datepicker").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
dayNamesMin: ["일", "월", "화", "수", "목", "금", "토"],
|
||||
monthNamesShort: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
|
||||
});
|
||||
|
||||
// ▼▼▼ [핵심 수정] 여러 파일 미리보기 기능 ▼▼▼
|
||||
const fileWrappers = document.querySelectorAll('.file_preview_wrapper');
|
||||
|
||||
fileWrappers.forEach((wrapper, index) => {
|
||||
const previewBox = wrapper.querySelector('.file_preview');
|
||||
const fileInput = wrapper.querySelector('input[type="file"]');
|
||||
const previewText = previewBox.querySelector('.preview_text');
|
||||
const existingFileInfo = wrapper.querySelector('.preview_info');
|
||||
|
||||
if (!previewBox || !fileInput) return;
|
||||
|
||||
// 1. 미리보기 박스를 클릭하면 숨겨진 파일 입력 필드가 클릭되도록 함
|
||||
// previewBox.addEventListener('click', () => {
|
||||
// fileInput.click();
|
||||
// });
|
||||
|
||||
// 2. 파일이 선택되었을 때의 동작
|
||||
fileInput.addEventListener('change', (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
// 기존 파일 정보가 있다면 숨김 (새 파일로 교체되므로)
|
||||
if (existingFileInfo) {
|
||||
existingFileInfo.style.display = 'none';
|
||||
}
|
||||
|
||||
if (file.type.startsWith('video/')) {
|
||||
// 동영상은 미리보기를 생성하지 않고 파일 이름만 표시
|
||||
previewBox.style.backgroundImage = 'none';
|
||||
previewText.textContent = `동영상: ${file.name}`;
|
||||
previewText.style.display = 'block';
|
||||
} else if (file.type.startsWith('image/')) {
|
||||
// 이미지는 FileReader를 사용해 미리보기 생성
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
console.log("sdfasdfasfd= > ",`url(${e.target.result})`)
|
||||
previewBox.style.backgroundImage = `url(${e.target.result})`;
|
||||
previewText.style.display = 'none'; // '클릭하여 파일 업로드' 텍스트 숨김
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// ▲▲▲ 여기까지 ▲▲▲
|
||||
});
|
||||
@@ -0,0 +1,71 @@
|
||||
// jQuery가 로드된 후 이 스크립트가 실행되어야 합니다.
|
||||
$(function() {
|
||||
// Datepicker 초기화
|
||||
$(".datepicker").datepicker({
|
||||
dateFormat: "yy-mm-dd",
|
||||
changeMonth: true,
|
||||
changeYear: true,
|
||||
dayNamesMin: ["일", "월", "화", "수", "목", "금", "토"],
|
||||
monthNamesShort: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
|
||||
});
|
||||
|
||||
// 노출 방식 라디오 버튼 제어
|
||||
const exposureRadios = $('input[name="wr_9"]');
|
||||
const reservationFields = $('#reservation_fields');
|
||||
|
||||
function toggleReservationFields() {
|
||||
if ($('input[name="wr_9"]:checked').val() === 'RESERVED') {
|
||||
reservationFields.slideDown();
|
||||
} else {
|
||||
reservationFields.slideUp();
|
||||
}
|
||||
}
|
||||
exposureRadios.on('change', toggleReservationFields);
|
||||
toggleReservationFields();
|
||||
|
||||
|
||||
// ▼▼▼ [핵심 수정] 여러 파일 미리보기 기능 ▼▼▼
|
||||
const fileWrappers = document.querySelectorAll('.file_preview_wrapper');
|
||||
|
||||
fileWrappers.forEach((wrapper, index) => {
|
||||
const previewBox = wrapper.querySelector('.file_preview');
|
||||
const fileInput = wrapper.querySelector('input[type="file"]');
|
||||
const previewText = previewBox.querySelector('.preview_text');
|
||||
const existingFileInfo = wrapper.querySelector('.preview_info');
|
||||
|
||||
if (!previewBox || !fileInput) return;
|
||||
|
||||
// 1. 미리보기 박스를 클릭하면 숨겨진 파일 입력 필드가 클릭되도록 함
|
||||
previewBox.addEventListener('click', () => {
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
// 2. 파일이 선택되었을 때의 동작
|
||||
fileInput.addEventListener('change', (event) => {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
// 기존 파일 정보가 있다면 숨김 (새 파일로 교체되므로)
|
||||
if (existingFileInfo) {
|
||||
existingFileInfo.style.display = 'none';
|
||||
}
|
||||
|
||||
if (file.type.startsWith('video/')) {
|
||||
// 동영상은 미리보기를 생성하지 않고 파일 이름만 표시
|
||||
previewBox.style.backgroundImage = 'none';
|
||||
previewText.textContent = `동영상: ${file.name}`;
|
||||
previewText.style.display = 'block';
|
||||
} else if (file.type.startsWith('image/')) {
|
||||
// 이미지는 FileReader를 사용해 미리보기 생성
|
||||
const reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
console.log("sdfasdfasfd= > ",`url(${e.target.result})`)
|
||||
previewBox.style.backgroundImage = `url(${e.target.result})`;
|
||||
previewText.style.display = 'none'; // '클릭하여 파일 업로드' 텍스트 숨김
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// ▲▲▲ 여기까지 ▲▲▲
|
||||
});
|
||||
Reference in New Issue
Block a user