테스트 사이트 - 개발 중인 베타 버전입니다

페이지를 열었을때 자동으로 검색하게 .... 채택완료

alexseo 8년 전 조회 3,287

class="col-sm-3 col-xs-6">

class="form-group">

 

위의 소스는 검색하기 소스입니다.

위의 소스를 미리 정해놓은 검색어를 

페이지를 열었을때 자동으로 검색하게 

하려면 어떻게 해야하나요?

감사합니다.

 

댓글을 작성하려면 로그인이 필요합니다.

답변 2개

채택된 답변
+20 포인트
8년 전

저건 검색하기 소스가 아니라 그냥 버튼 이잖아요

자바스크립트로 검색폼을 submit 시키면 됩니다

 

response.json()) .then(data => { if (data.success) { countSpan.textContent = data.good_count; if (data.user_vote === null) { // 취소된 경우 textSpan.textContent = '좋아요'; this.classList.remove('bg-blue-100', 'dark:bg-blue-900', 'text-blue-700', 'dark:text-blue-300'); this.classList.add('bg-green-100', 'dark:bg-green-900', 'text-green-700', 'dark:text-green-300', 'hover:bg-green-200', 'dark:hover:bg-green-800'); } else { // 투표된 경우 textSpan.textContent = '좋아요됨'; this.classList.remove('bg-green-100', 'dark:bg-green-900', 'text-green-700', 'dark:text-green-300', 'hover:bg-green-200', 'dark:hover:bg-green-800'); this.classList.add('bg-blue-100', 'dark:bg-blue-900', 'text-blue-700', 'dark:text-blue-300'); } console.log('Success message:', data.message); showMessage(data.message, 'success'); } else { console.log('Error message:', data.error); showMessage(data.error || '좋아요에 실패했습니다.', 'error'); } this.disabled = false; this.classList.remove('opacity-50'); }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); this.disabled = false; this.classList.remove('opacity-50'); }); }); } // 싫어요 기능 const voteNogoodBtn = document.getElementById('vote-nogood-btn'); if (voteNogoodBtn) { voteNogoodBtn.addEventListener('click', function() { const wrId = this.dataset.wrId; const countSpan = this.querySelector('.vote-nogood-count'); const textSpan = this.querySelector('.vote-nogood-text'); const isVoted = textSpan.textContent === '싫어요됨'; if (this.disabled) return; this.disabled = true; this.classList.add('opacity-50'); fetch(`/questions/${wrId}/vote`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ type: 'nogood' }) }) .then(response => response.json()) .then(data => { if (data.success) { countSpan.textContent = data.nogood_count; if (data.user_vote === null) { // 취소된 경우 textSpan.textContent = '싫어요'; this.classList.remove('bg-orange-100', 'dark:bg-orange-900', 'text-orange-700', 'dark:text-orange-300'); this.classList.add('bg-red-100', 'dark:bg-red-900', 'text-red-700', 'dark:text-red-300', 'hover:bg-red-200', 'dark:hover:bg-red-800'); } else { // 투표된 경우 textSpan.textContent = '싫어요됨'; this.classList.remove('bg-red-100', 'dark:bg-red-900', 'text-red-700', 'dark:text-red-300', 'hover:bg-red-200', 'dark:hover:bg-red-800'); this.classList.add('bg-orange-100', 'dark:bg-orange-900', 'text-orange-700', 'dark:text-orange-300'); } console.log('Success message:', data.message); showMessage(data.message, 'success'); } else { console.log('Error message:', data.error); showMessage(data.error || '싫어요에 실패했습니다.', 'error'); } this.disabled = false; this.classList.remove('opacity-50'); }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); this.disabled = false; this.classList.remove('opacity-50'); }); }); } // 스크랩 기능 const scrapBtn = document.getElementById('scrap-btn'); if (scrapBtn) { scrapBtn.addEventListener('click', function() { const wrId = this.dataset.wrId; const countSpan = this.querySelector('.scrap-count'); this.disabled = true; this.classList.add('opacity-50'); fetch(`/questions/${wrId}/scrap`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' } }) .then(response => response.json()) .then(data => { if (data.success) { countSpan.textContent = `(${data.count})`; const textSpan = this.querySelector('.scrap-text'); const iconSpan = this.querySelector('i'); // 스크랩된 상태로 변경 textSpan.textContent = '스크랩됨'; iconSpan.className = 'fa fa-bookmark mr-1'; this.classList.remove('bg-gray-100', 'dark:bg-gray-700', 'text-gray-700', 'dark:text-gray-300', 'hover:bg-gray-200', 'dark:hover:bg-gray-600'); this.classList.add('bg-yellow-100', 'dark:bg-yellow-900', 'text-yellow-700', 'dark:text-yellow-300'); // 스크랩 후 버튼 비활성화 this.disabled = true; showMessage(data.message, 'success'); } else { showMessage(data.error || '스크랩에 실패했습니다.', 'error'); } this.disabled = false; this.classList.remove('opacity-50'); }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); this.disabled = false; this.classList.remove('opacity-50'); }); }); } // 신고 기능 document.querySelectorAll('button[id^=qa_singo-]').forEach(button => { button.addEventListener('click', function() { const idParts = this.id.split('-'); const bo_table = idParts[1]; const wr_id = idParts[2]; const radios_reason = ["#rdo_reason_ad", "#rdo_reason_ob", "#rdo_reason_ha", "#rdo_reason_etc"]; // 모달 다이얼로그 표시 const modal = document.getElementById('sir_react_singod'); modal.style.display = 'block'; modal.style.position = 'fixed'; modal.style.top = '50%'; modal.style.left = '50%'; modal.style.transform = 'translate(-50%, -50%)'; modal.style.backgroundColor = 'white'; modal.style.padding = '20px'; modal.style.borderRadius = '8px'; modal.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'; modal.style.zIndex = '1000'; modal.style.minWidth = '400px'; // 배경 오버레이 const overlay = document.createElement('div'); overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100%'; overlay.style.height = '100%'; overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; overlay.style.zIndex = '999'; document.body.appendChild(overlay); // 신고하기 버튼 const reportBtn = document.createElement('button'); reportBtn.textContent = '신고하기'; reportBtn.className = 'px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 mr-2'; reportBtn.addEventListener('click', function() { let r_checked = false; let reason = ''; radios_reason.forEach(radioId => { if (document.querySelector(radioId).checked) { r_checked = true; if (radioId === '#rdo_reason_etc') { const customReason = document.getElementById('sg_reason').value.trim(); if (customReason.length < 10) { alert('기타 선택시 신고사유를 10글자 이상 입력하십시오.'); return; } reason = customReason; } else { reason = document.querySelector(radioId).value; } } }); if (!r_checked) { alert('신고사유를 선택하세요.'); return; } // 신고 요청 fetch(`/questions/${wr_id}/singo`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ bo_table: bo_table, reason: reason, q_mode: 'singo' }) }) .then(response => response.json()) .then(data => { if (data.error) { alert(data.error); return; } // 모달 닫기 modal.style.display = 'none'; document.body.removeChild(overlay); // 신고 카운트 업데이트 const countElement = document.querySelector(`#qa_singo-${bo_table}-${wr_id} .singo-count`); if (countElement) { countElement.textContent = data.count; } // 버튼 비활성화 button.disabled = true; button.classList.add('opacity-50'); alert(data.message); }) .catch(error => { console.error('Error:', error); alert('신고 처리 중 오류가 발생했습니다.'); }); }); // 취소 버튼 const cancelBtn = document.createElement('button'); cancelBtn.textContent = '취소'; cancelBtn.className = 'px-4 py-2 bg-gray-500 text-white rounded-lg hover:bg-gray-600'; cancelBtn.addEventListener('click', function() { modal.style.display = 'none'; document.body.removeChild(overlay); }); // 기존 버튼들 제거 const existingButtons = modal.querySelectorAll('button'); existingButtons.forEach(btn => btn.remove()); // 버튼들 추가 const buttonContainer = document.createElement('div'); buttonContainer.className = 'mt-4 text-right'; buttonContainer.appendChild(reportBtn); buttonContainer.appendChild(cancelBtn); modal.appendChild(buttonContainer); // 오버레이 클릭 시 닫기 overlay.addEventListener('click', function() { modal.style.display = 'none'; document.body.removeChild(overlay); }); }); }); // 공유 기능 const shareBtn = document.getElementById('share-btn'); if (shareBtn) { shareBtn.addEventListener('click', function() { const shareModal = document.getElementById('share-modal'); const currentUrl = window.location.href; const title = document.title; // SNS 공유 링크 설정 const facebookUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(currentUrl)}`; const twitterUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(currentUrl)}&text=${encodeURIComponent(title)}`; document.getElementById('facebook-share').href = facebookUrl; document.getElementById('twitter-share').href = twitterUrl; shareModal.classList.remove('hidden'); }); } // 메시지 표시 함수 }); // 공유 모달 닫기 function closeShareModal() { document.getElementById('share-modal').classList.add('hidden'); } // 클립보드에 복사 function copyToClipboard() { navigator.clipboard.writeText(window.location.href).then(function() { showMessage('링크가 클립보드에 복사되었습니다.', 'success'); closeShareModal(); }); } // Image preview function function previewImage(imageUrl, filename) { // Create modal overlay const overlay = document.createElement('div'); overlay.className = 'fixed inset-0 bg-black bg-opacity-75 z-50 flex items-center justify-center p-4'; overlay.onclick = function() { document.body.removeChild(overlay); }; // Create modal content const modal = document.createElement('div'); modal.className = 'bg-white dark:bg-gray-800 rounded-lg max-w-4xl max-h-full overflow-auto'; modal.onclick = function(e) { e.stopPropagation(); }; modal.innerHTML = `

${filename}

${filename}
`; overlay.appendChild(modal); document.body.appendChild(overlay); } // 메시지 표시 함수 function showMessage(message, type = 'info') { console.log('showMessage called:', message, type); // 기존 메시지 제거 const existingMessage = document.querySelector('.message-toast'); if (existingMessage) { existingMessage.remove(); } // 새 메시지 생성 const messageDiv = document.createElement('div'); messageDiv.className = 'message-toast fixed top-4 right-4 z-50 px-6 py-3 rounded-lg shadow-lg transition-all duration-300'; if (type === 'success') { messageDiv.className += ' bg-green-500 text-white'; } else if (type === 'error') { messageDiv.className += ' bg-red-500 text-white'; } else { messageDiv.className += ' bg-blue-500 text-white'; } messageDiv.textContent = message; document.body.appendChild(messageDiv); console.log('Message displayed:', messageDiv); // 3초 후 자동 제거 setTimeout(() => { if (messageDiv.parentNode) { messageDiv.style.opacity = '0'; messageDiv.style.transform = 'translateX(100%)'; setTimeout(() => { if (messageDiv.parentNode) { messageDiv.parentNode.removeChild(messageDiv); } }, 300); } }, 3000); } // 답변 작성 폼 처리 document.addEventListener('DOMContentLoaded', function() { // 답변 작성 폼 const answerForm = document.getElementById('answer-form-element'); if (answerForm) { answerForm.addEventListener('submit', function(e) { e.preventDefault(); // 기본 폼 제출 방지 // 중복 제출 방지 const submitBtn = this.querySelector('button[type="submit"]'); if (submitBtn.disabled) { return; } // 버튼 비활성화 submitBtn.disabled = true; submitBtn.textContent = '등록 중...'; // CKEditor 내용 가져오기 const content = CKEDITOR.instances.wr_content ? CKEDITOR.instances.wr_content.getData() : ''; // FormData 생성 const formData = new FormData(); formData.append('_token', document.querySelector('input[name="_token"]').value); formData.append('wr_qa_id', document.querySelector('input[name="wr_qa_id"]').value); formData.append('wr_content', content); // AJAX 요청 fetch('https://new-sir.gnuboard.net/questions/answer', { method: 'POST', body: formData, headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }) .then(response => response.json()) .then(data => { if (data.success) { // 성공 메시지 표시 showMessage('답변이 등록되었습니다.', 'success'); // 페이지 새로고침하여 새 답변 표시 window.location.reload(); } else { // 에러 메시지 표시 showMessage(data.message || '답변 등록 중 오류가 발생했습니다.', 'error'); // 버튼 복원 submitBtn.disabled = false; submitBtn.textContent = '답변 등록'; } }) .catch(error => { console.error('Error:', error); showMessage('답변 등록 중 오류가 발생했습니다.', 'error'); // 버튼 복원 submitBtn.disabled = false; submitBtn.textContent = '답변 등록'; }); }); } // URL 프래그먼트 처리 function handleFragment() { const hash = window.location.hash; if (hash === '#new-answer') { // URL에서 프래그먼트 제거 (히스토리 정리) history.replaceState(null, null, window.location.pathname + window.location.search); setTimeout(() => { // 답변 목록에서 가장 최근 답변 찾기 const answers = document.querySelectorAll('.answer-item'); if (answers.length > 0) { const lastAnswer = answers[answers.length - 1]; lastAnswer.scrollIntoView({ behavior: 'smooth', block: 'start' }); // 새 답변에 하이라이트 효과 추가 lastAnswer.style.backgroundColor = '#fef3c7'; lastAnswer.style.transition = 'background-color 0.3s ease'; setTimeout(() => { lastAnswer.style.backgroundColor = ''; }, 3000); } }, 500); } } // 페이지 로드 시 프래그먼트 처리 handleFragment(); // 해시 변경 이벤트 리스너 (브라우저 뒤로가기/앞으로가기 대응) window.addEventListener('hashchange', handleFragment); }); // 답변 좋아요/싫어요 기능 document.addEventListener('DOMContentLoaded', function() { // 답변 좋아요 버튼 document.querySelectorAll('.vote-good-btn').forEach(button => { if (button.id !== 'vote-good-btn') { // 질문 좋아요 버튼 제외 button.addEventListener('click', function() { const wrId = this.dataset.wrId; const countSpan = this.querySelector('.vote-good-count'); const textSpan = this.querySelector('.vote-good-text'); const isVoted = textSpan.textContent === '좋아요됨'; if (this.disabled) return; this.disabled = true; this.classList.add('opacity-50'); fetch(`/questions/${wrId}/vote`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ type: 'good' }) }) .then(response => response.json()) .then(data => { if (data.success) { countSpan.textContent = data.good_count; if (data.user_vote === null) { // 취소된 경우 textSpan.textContent = '좋아요'; this.classList.remove('bg-blue-100', 'dark:bg-blue-700', 'text-blue-700', 'dark:text-blue-300'); this.classList.add('bg-gray-100', 'dark:bg-gray-700', 'text-gray-700', 'dark:text-gray-300', 'hover:bg-gray-200', 'dark:hover:bg-gray-600'); } else { // 투표된 경우 textSpan.textContent = '좋아요됨'; this.classList.remove('bg-gray-100', 'dark:bg-gray-700', 'text-gray-700', 'dark:text-gray-300', 'hover:bg-gray-200', 'dark:hover:bg-gray-600'); this.classList.add('bg-blue-100', 'dark:bg-blue-700', 'text-blue-700', 'dark:text-blue-300'); } showMessage(data.message, 'success'); } else { showMessage(data.error || '좋아요에 실패했습니다.', 'error'); } this.disabled = false; this.classList.remove('opacity-50'); }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); this.disabled = false; this.classList.remove('opacity-50'); }); }); } }); // 답변 싫어요 버튼 document.querySelectorAll('.vote-nogood-btn').forEach(button => { if (button.id !== 'vote-nogood-btn') { // 질문 싫어요 버튼 제외 button.addEventListener('click', function() { const wrId = this.dataset.wrId; const countSpan = this.querySelector('.vote-nogood-count'); const textSpan = this.querySelector('.vote-nogood-text'); const isVoted = textSpan.textContent === '싫어요됨'; if (this.disabled) return; this.disabled = true; this.classList.add('opacity-50'); fetch(`/questions/${wrId}/vote`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ type: 'nogood' }) }) .then(response => response.json()) .then(data => { if (data.error === '') { countSpan.textContent = data.count; if (data.cancle_vote === 'cancle') { // 취소된 경우 textSpan.textContent = '싫어요'; this.classList.remove('bg-orange-100', 'dark:bg-orange-700', 'text-orange-700', 'dark:text-orange-300'); this.classList.add('bg-gray-100', 'dark:bg-gray-700', 'text-gray-700', 'dark:text-gray-300', 'hover:bg-gray-200', 'dark:hover:bg-gray-600'); } else { // 투표된 경우 textSpan.textContent = '싫어요됨'; this.classList.remove('bg-gray-100', 'dark:bg-gray-700', 'text-gray-700', 'dark:text-gray-300', 'hover:bg-gray-200', 'dark:hover:bg-gray-600'); this.classList.add('bg-orange-100', 'dark:bg-orange-700', 'text-orange-700', 'dark:text-orange-300'); } showMessage(data.message, 'success'); } else { showMessage(data.error || '싫어요에 실패했습니다.', 'error'); } this.disabled = false; this.classList.remove('opacity-50'); }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); this.disabled = false; this.classList.remove('opacity-50'); }); }); } }); // 채택 버튼 document.querySelectorAll('.adopt-btn').forEach(button => { button.addEventListener('click', function() { const questionId = this.dataset.questionId; const answerId = this.dataset.answerId; if (!confirm('이 답변을 채택하시겠습니까?\n\n채택된 답변은 변경할 수 없습니다.')) { return; } fetch(`/questions/${questionId}/adopt/${answerId}`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }) .then(response => response.json()) .then(data => { if (data.success) { showMessage(data.message, 'success'); // 페이지 새로고침하여 채택 상태 반영 setTimeout(() => { location.reload(); }, 1500); } else { showMessage(data.error || '채택에 실패했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); }); }); }); // 채택 취소 버튼 document.querySelectorAll('.unadopt-btn').forEach(button => { button.addEventListener('click', function() { const questionId = this.dataset.questionId; if (!confirm('채택을 취소하시겠습니까?\n\n채택된 답변 작성자에게 지급된 포인트가 회수됩니다.')) { return; } fetch(`/questions/${questionId}/unadopt`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }) .then(response => response.json()) .then(data => { if (data.success) { showMessage(data.message, 'success'); // 페이지 새로고침하여 채택 취소 상태 반영 setTimeout(() => { location.reload(); }, 1500); } else { showMessage(data.error || '채택 취소에 실패했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); }); }); }); // 댓글 작성 document.querySelectorAll('.comment-form-element').forEach(form => { form.addEventListener('submit', function(e) { e.preventDefault(); // 중복 제출 방지 const submitBtn = this.querySelector('button[type="submit"]'); if (submitBtn.disabled) { return; } const parentId = this.dataset.parentId; const content = this.querySelector('textarea[name="wr_content"]').value.trim(); if (!content) { showMessage('댓글 내용을 입력해주세요.', 'error'); return; } // 버튼 비활성화 submitBtn.disabled = true; submitBtn.textContent = '등록 중...'; const formData = new FormData(); formData.append('wr_qa_id', parentId); formData.append('wr_content', content); formData.append('_token', document.querySelector('meta[name="csrf-token"]').getAttribute('content')); fetch('/questions/comment', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { showMessage(data.message, 'success'); // 페이지 새로고침하여 댓글 반영 setTimeout(() => { location.reload(); }, 1000); } else { showMessage(data.error || '댓글 등록에 실패했습니다.', 'error'); // 실패 시 버튼 다시 활성화 submitBtn.disabled = false; submitBtn.textContent = '댓글 등록'; } }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); // 오류 시 버튼 다시 활성화 submitBtn.disabled = false; submitBtn.textContent = '댓글 등록'; }); }); }); // 댓글 수정 document.querySelectorAll('.edit-comment-btn').forEach(button => { button.addEventListener('click', function() { const commentContainer = this.closest('.relative'); const commentContent = commentContainer.querySelector('.comment-content'); const editForm = commentContainer.querySelector('.comment-edit-form'); const textarea = editForm.querySelector('textarea'); // 편집 모드로 전환 commentContent.classList.add('hidden'); editForm.classList.remove('hidden'); textarea.focus(); }); }); // 댓글 저장 document.querySelectorAll('.comment-save-btn').forEach(button => { button.addEventListener('click', function() { const commentId = this.dataset.commentId; const commentContainer = this.closest('.relative'); const textarea = commentContainer.querySelector('textarea'); const newContent = textarea.value.trim(); if (!newContent) { showMessage('댓글 내용을 입력해주세요.', 'error'); return; } fetch(`/questions/comment/${commentId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') }, body: JSON.stringify({ wr_content: newContent }) }) .then(response => response.json()) .then(data => { if (data.success) { showMessage(data.message, 'success'); // 페이지 새로고침하여 수정된 댓글 반영 setTimeout(() => { location.reload(); }, 1000); } else { showMessage(data.error || '댓글 수정에 실패했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); }); }); }); // 댓글 수정 취소 document.querySelectorAll('.comment-cancel-btn').forEach(button => { button.addEventListener('click', function() { const commentContainer = this.closest('.relative'); const commentContent = commentContainer.querySelector('.comment-content'); const editForm = commentContainer.querySelector('.comment-edit-form'); const textarea = editForm.querySelector('textarea'); // 원래 내용으로 복원 textarea.value = commentContent.textContent.trim(); // 편집 모드 해제 editForm.classList.add('hidden'); commentContent.classList.remove('hidden'); }); }); // 댓글 삭제 document.querySelectorAll('.delete-comment-btn').forEach(button => { button.addEventListener('click', function() { const commentId = this.dataset.commentId; if (!confirm('정말로 이 댓글을 삭제하시겠습니까?')) { return; } fetch(`/questions/comment/${commentId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }) .then(response => response.json()) .then(data => { if (data.success) { showMessage(data.message, 'success'); // 페이지 새로고침하여 삭제된 댓글 반영 setTimeout(() => { location.reload(); }, 1000); } else { showMessage(data.error || '댓글 삭제에 실패했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); }); }); }); // 대댓글 답글 버튼 클릭 document.querySelectorAll('.reply-comment-btn').forEach(button => { button.addEventListener('click', function() { const commentId = this.getAttribute('data-comment-id'); const commentAuthor = this.getAttribute('data-comment-author'); const replyForm = this.closest('.relative').querySelector('.reply-form'); const replyTarget = replyForm.querySelector('.reply-target'); // 다른 대댓글 폼들 숨기기 document.querySelectorAll('.reply-form').forEach(form => { if (form !== replyForm) { form.classList.add('hidden'); } }); // 현재 대댓글 폼 토글 replyForm.classList.toggle('hidden'); // 답글 대상 표시 replyTarget.textContent = `${commentAuthor}님에게 답글`; // 폼이 보이면 textarea에 포커스 if (!replyForm.classList.contains('hidden')) { const textarea = replyForm.querySelector('textarea'); textarea.focus(); } }); }); // 대댓글 취소 버튼 document.querySelectorAll('.reply-cancel-btn').forEach(button => { button.addEventListener('click', function() { const replyForm = this.closest('.reply-form'); const textarea = replyForm.querySelector('textarea'); // 내용 초기화 textarea.value = ''; // 폼 숨기기 replyForm.classList.add('hidden'); }); }); // 대댓글 등록 document.querySelectorAll('.reply-form-element').forEach(form => { form.addEventListener('submit', function(e) { e.preventDefault(); // 중복 제출 방지 const submitBtn = this.querySelector('button[type="submit"]'); if (submitBtn.disabled) { return; } const formData = new FormData(this); const parentId = this.getAttribute('data-parent-id'); const commentId = this.getAttribute('data-comment-id'); const textarea = this.querySelector('textarea[name="wr_content"]'); const content = textarea.value.trim(); if (!content) { showMessage('답글 내용을 입력해주세요.', 'error'); return; } // 버튼 비활성화 submitBtn.disabled = true; submitBtn.textContent = '등록 중...'; // 답글 대상 정보 추가 formData.append('wr_comment_reply', commentId); formData.append('wr_qa_id', parentId); formData.append('parent_id', parentId); fetch(`/questions/comment`, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => response.json()) .then(data => { if (data.success) { showMessage('답글이 등록되었습니다.', 'success'); textarea.value = ''; this.closest('.reply-form').classList.add('hidden'); // 페이지 새로고침으로 새 답글 표시 setTimeout(() => { location.reload(); }, 1000); } else { showMessage(data.error || '답글 등록 중 오류가 발생했습니다.', 'error'); // 실패 시 버튼 다시 활성화 submitBtn.disabled = false; submitBtn.textContent = '답글 등록'; } }) .catch(error => { console.error('Error:', error); showMessage('네트워크 오류가 발생했습니다.', 'error'); // 오류 시 버튼 다시 활성화 submitBtn.disabled = false; submitBtn.textContent = '답글 등록'; }); }); }); }); // 프래그먼트 식별자 스크롤 처리 document.addEventListener('DOMContentLoaded', function() { // URL에 프래그먼트가 있는지 확인 if (window.location.hash) { const hash = window.location.hash.substring(1); // # 제거 const targetElement = document.getElementById(hash); if (targetElement) { // 약간의 지연 후 스크롤 (페이지 로딩 완료 후) setTimeout(() => { const headerHeight = 120; // 헤더 높이 + 여백 const elementPosition = targetElement.offsetTop; const offsetPosition = elementPosition - headerHeight; window.scrollTo({ top: offsetPosition, behavior: 'smooth' }); }, 100); } } }); // 답변 정렬 기능 document.addEventListener('DOMContentLoaded', function() { const sortSelect = document.getElementById('qa_sort_select'); if (sortSelect) { sortSelect.addEventListener('change', function() { const sortValue = this.value; const currentUrl = new URL(window.location); currentUrl.searchParams.set('vsst', sortValue); currentUrl.searchParams.set('vpage', '1'); // 정렬 변경 시 첫 페이지로 currentUrl.hash = '#qa_answer'; window.location.href = currentUrl.toString(); }); } }); // 답변 삭제 기능 document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.delete-answer-btn').forEach(button => { button.addEventListener('click', function() { const answerId = this.getAttribute('data-answer-id'); if (confirm('정말로 이 답변을 삭제하시겠습니까?')) { fetch(`/questions/${answerId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }) .then(response => response.json()) .then(data => { if (data.success) { // 답변 요소 제거 const answerElement = document.getElementById(`answer_${answerId}`); if (answerElement) { answerElement.remove(); } // 답변 수 업데이트 (전체 답변 수에서 1 감소) const answerCountElement = document.querySelector('h2'); if (answerCountElement) { const currentCount = parseInt(answerCountElement.textContent.match(/\d+/)[0]); answerCountElement.textContent = `답변 ${currentCount - 1}개`; } // 페이지 새로고침 (전체 답변 수와 페이징을 정확히 반영하기 위해) setTimeout(() => { window.location.reload(); }, 1000); showMessage('답변이 삭제되었습니다.', 'success'); } else { showMessage(data.message || '답변 삭제 중 오류가 발생했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('답변 삭제 중 오류가 발생했습니다.', 'error'); }); } }); }); }); // 미채택 완료 function closeWithoutAdopt(questionId) { if (!confirm('답변을 채택하지 않고 질문을 완료하시겠습니까?\n\n이 작업은 취소할 수 없습니다.')) { return; } fetch(`/questions/${questionId}/close-without-adopt`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' } }) .then(response => response.json()) .then(data => { if (data.success) { showMessage('질문이 미채택 완료되었습니다.', 'success'); setTimeout(() => { window.location.reload(); }, 1500); } else { showMessage(data.error || '처리에 실패했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('처리 중 오류가 발생했습니다.', 'error'); }); } // 재등록 function reregisterQuestion(questionId) { if (!confirm('이 질문을 재등록하시겠습니까?\n\n재등록하면 새로운 답변을 받을 수 있습니다.')) { return; } fetch(`/questions/${questionId}/reregister`, { method: 'POST', headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'), 'Content-Type': 'application/json', 'Accept': 'application/json' } }) .then(response => response.json()) .then(data => { if (data.success) { showMessage('질문이 재등록되었습니다.', 'success'); if (data.redirect) { setTimeout(() => { window.location.href = data.redirect; }, 1500); } else { setTimeout(() => { window.location.reload(); }, 1500); } } else { showMessage(data.error || '처리에 실패했습니다.', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('처리 중 오류가 발생했습니다.', 'error'); }); } // Prism.js용 코드 복사 기능 function copyCodePrism(button) { // 버튼의 부모 요소에서 코드 블록 찾기 const wrapper = button.closest('.code-block-wrapper'); const codeBlock = wrapper.querySelector('code'); const codeText = codeBlock.textContent; // 클립보드에 복사 navigator.clipboard.writeText(codeText).then(() => { // 버튼 텍스트 임시 변경 const originalHTML = button.innerHTML; const originalStyle = { background: button.style.background, borderColor: button.style.borderColor, color: button.style.color }; button.innerHTML = ' Copied!'; button.style.background = 'rgba(72, 187, 120, 0.7)'; button.style.borderColor = 'rgba(72, 187, 120, 0.9)'; button.style.color = '#fff'; // 2초 후 원래 상태로 복구 setTimeout(() => { button.innerHTML = originalHTML; button.style.background = originalStyle.background; button.style.borderColor = originalStyle.borderColor; button.style.color = originalStyle.color; }, 2000); }).catch(err => { console.error('Failed to copy code:', err); // Fallback: 전통적인 복사 방법 사용 const textArea = document.createElement('textarea'); textArea.value = codeText; textArea.style.position = 'fixed'; textArea.style.left = '-999999px'; document.body.appendChild(textArea); textArea.select(); try { document.execCommand('copy'); // 성공 표시 const originalHTML = button.innerHTML; button.innerHTML = ' Copied!'; setTimeout(() => { button.innerHTML = originalHTML; }, 2000); } catch (err) { alert('코드 복사에 실패했습니다.'); } document.body.removeChild(textArea); }); }