상품 보기 - 문의

<p>Q&A ( <th:block th:text="${inquiryPageResponseDTO.total}"></th:block> )</p>
<div>
    <p>
        답변은 <span>마이롯데>나의문의내역</span>에서 확인하실 수 있습니다.<br>
        처음 확인 시, 필터가 적용된 상태로 <span>비밀글 제외한 Q&A</span>가 노출됩니다.
    </p>
    <button type="button">문의하기</button>
</div>

<th:block th:each="inquiry : ${inquiryPageResponseDTO.dtoList}">
    <div class="qna_content">
        <p th:text="${inquiry.cateV1} + ' > ' + ${inquiry.cateV2}"></p>
        <p th:text="${inquiry.content}"></p>
        <div class="answer" th:if="${inquiry.answer != null}">
            <p th:text="${inquiry.answer}"></p>
            <p>롯데쇼핑(주)본점<span>판매자</span></p>
        </div>
        <div class="no-answer" th:if="${inquiry.answer == null}">
            <p>답변 대기 중입니다.</p>
        </div>
        <div>
            <a href="#">답변달기</a>
            <p th:text="${#temporals.format(inquiry.wdate, 'yyyy.MM.dd')}"></p>
        </div>
    </div>
</th:block>

<div id="qnaModal" class="modal">
    <div class="modal-content">
        <span class="close-button">&times;</span>
        <h3>문의 내용</h3>
        <p id="modalInquiryContent"></p>
        <h3>답변</h3>
        <div id="modalAnswerContent"></div>
    </div>
</div>

<div class="qna_page">
    <a href="#" th:if="${inquiryPageResponseDTO.prev}" th:attr="data-page=${inquiryPageResponseDTO.start - 1}">&lt;</a>
    <th:block th:each="num : ${#numbers.sequence(inquiryPageResponseDTO.start, inquiryPageResponseDTO.end)}">
        <a href="#" th:attr="data-page=${num}" th:class="${num == inquiryPageResponseDTO.pg ? 'current' : 'num'}" th:text="${num}">1</a>
    </th:block>
    <a href="#" th:if="${inquiryPageResponseDTO.next}" th:attr="data-page=${inquiryPageResponseDTO.end + 1}">&gt;</a>
</div>

기술 설명

Q\&A 목록 AJAX 처리 기능 (view.js)

const prodNoElement = document.getElementById('prodNo');
const qnaEl = document.querySelector('.qna_content');
const qnaContainer = qnaEl ? qnaEl.parentNode : null;
const qnaPagination = document.querySelector('.qna_page');

// AJAX 응답으로 Q&A 목록과 페이징 생성
function updateQnaListUI(qnaData) {
    if (qnaData && Array.isArray(qnaData.dtoList)) {
        // 기존 Q&A 항목 제거
        const existingQnaContents = qnaContainer.querySelectorAll('.qna_content');
        existingQnaContents.forEach(content => content.remove());

        // Q&A 항목 렌더링
        qnaData.dtoList.forEach(inquiry => {
            const qnaContent = document.createElement('div');
            qnaContent.classList.add('qna_content');
            qnaContent.innerHTML = `
                <p>${inquiry.cateV1} > ${inquiry.cateV2}</p>
                <p>${inquiry.content}</p>
                <div class="answer">${inquiry.answer
                    ? `<p>${inquiry.answer}</p><p>롯데쇼핑(주)본점<span>판매자</span></p>`
                    : '<p>답변 대기 중입니다.</p>'
                }</div>
                <div>
                    <a href="#">답변달기</a>
                    <p>${new Date(inquiry.wdate).toLocaleDateString('ko-KR', {
                        year: 'numeric',
                        month: '2-digit',
                        day: '2-digit'
                    })}</p>
                </div>
            `;
            qnaContainer.appendChild(qnaContent);
        });

        // 페이징 초기화
        qnaPagination.innerHTML = '';

        // 이전 페이지 링크
        if (qnaData.prev) {
            const prevLink = document.createElement('a');
            prevLink.href = '#';
            prevLink.textContent = '<';
            prevLink.setAttribute('data-page', qnaData.start - 1);
            qnaPagination.appendChild(prevLink);
        }

        // 페이지 번호 링크
        for (let i = qnaData.start; i <= qnaData.end; i++) {
            const pageLink = document.createElement('a');
            pageLink.href = '#';
            pageLink.textContent = i;
            pageLink.setAttribute('data-page', i);
            pageLink.classList.add(i === qnaData.pg ? 'current' : 'num');
            qnaPagination.appendChild(pageLink);
        }

        // 다음 페이지 링크
        if (qnaData.next) {
            const nextLink = document.createElement('a');
            nextLink.href = '#';
            nextLink.textContent = '>';
            nextLink.setAttribute('data-page', qnaData.end + 1);
            qnaPagination.appendChild(nextLink);
        }

        qnaContainer.appendChild(qnaPagination);
    }
}

// Q&A 목록을 AJAX로 요청
function fetchQnaList(page, prodNo) {
    const url = `/product/qnaList?pg=${page}&prodNo=${prodNo}`;
    fetch(url)
        .then(response => {
            if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
            return response.json();
        })
        .then(data => {
            updateQnaListUI(data);
        })
        .catch(error => {
            console.error('Q&A 목록 로드 실패:', error);
        });
}

// 초기 Q&A 요청
if (prodNoElement) {
    fetchQnaList(1, prodNoElement.value);
}

// 페이지 번호 클릭 시 AJAX 재호출
qnaPagination.addEventListener('click', function (event) {
    if (event.target.tagName === 'A' && event.target.hasAttribute('data-page') && prodNoElement) {
        event.preventDefault();
        const pageNumber = parseInt(event.target.getAttribute('data-page'));
        const prodNoValue = prodNoElement.value;
        if (!isNaN(pageNumber) && pageNumber > 0 && prodNoValue) {
            fetchQnaList(pageNumber, prodNoValue);
        }
    }
});

기능 설명

Q\&A 모달 보기 기능

// Q&A 항목 클릭 시 모달 열기 (이벤트 위임)
document.addEventListener('click', function (event) {
    if (event.target.classList.contains('qna_content')) {
        const qnaModal = document.getElementById("qnaModal");
        const modalInquiryContent = document.getElementById("modalInquiryContent");
        const modalAnswerContent = document.getElementById("modalAnswerContent");
        const qnaContentElement = event.target;

        // 문의 텍스트와 답변 텍스트 추출
        const inquiryTextElement = qnaContentElement.querySelector("p:nth-child(2)");
        const answerDiv = qnaContentElement.querySelector(".answer");
        let answerText = answerDiv ? answerDiv.innerHTML : "<p>답변 대기 중입니다.</p>";

        if (inquiryTextElement) {
            modalInquiryContent.textContent = inquiryTextElement.textContent;
        }
        modalAnswerContent.innerHTML = answerText;

        if (qnaModal) {
            qnaModal.style.display = "block";
        }
    }
});

// 모달 닫기 (× 버튼 및 바깥 클릭)
const closeBtn = document.querySelector("#qnaModal .close-button");
if (closeBtn) {
    closeBtn.onclick = function () {
        const qnaModal = document.getElementById("qnaModal");
        if (qnaModal) {
            qnaModal.style.display = "none";
        }
    };
}
window.onclick = function (event) {
    const qnaModal = document.getElementById("qnaModal");
    if (event.target === qnaModal) {
        qnaModal.style.display = "none";
    }
};

기능 설명