Files
survey/js/survey.js
T
2026-09-12 14:34:09 +07:00

297 lines
13 KiB
JavaScript

/**
* TPU Survey - Public Survey Response Logic
* รองรับ Section -> Heading -> Question
*/
let currentSurvey = null;
async function initSurvey() {
const params = new URLSearchParams(window.location.search);
const link = params.get('link');
if (!link) {
showError('ไม่พบลิงก์แบบสอบถาม');
return;
}
try {
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
const data = await fetch(`${basePath}/api/surveys.php?action=getByLink&link=${encodeURIComponent(link)}`).then(r => r.json());
if (data.error) {
showError(data.error);
return;
}
currentSurvey = data.survey;
renderSurvey();
} catch (err) {
showError('ไม่สามารถโหลดแบบสอบถามได้');
}
}
function showError(msg) {
document.getElementById('surveyContent').innerHTML = `
<div class="empty-state" style="padding:80px 20px;">
<div class="empty-icon">😔</div>
<h3>${msg}</h3>
<p class="text-muted mt-8">ลิงก์อาจไม่ถูกต้องหรือแบบสอบถามถูกปิดแล้ว</p>
</div>
`;
}
function renderSurvey() {
const container = document.getElementById('surveyContent');
let html = `
<div class="survey-header" style="text-align:center;">
<img src="pic/logo.png" alt="TPU Logo" style="display: block; margin-left: auto; margin-right: auto; margin-bottom: 16px; height: 80px; width: auto;">
<h1>${escapeHtml(currentSurvey.title)}</h1>
${currentSurvey.description ? `<p>${escapeHtml(currentSurvey.description)}</p>` : ''}
</div>
<form id="surveyResponseForm" onsubmit="submitSurveyResponse(event)">
${currentSurvey.has_certificate == 1 ? `
<!-- ส่วนข้อมูลสำหรับรับเกียรติบัตร -->
<div class="survey-section" style="border-top: 4px solid var(--primary-color, #2563eb);">
<div class="survey-section-header">
<h2 style="font-size:1.2rem; font-weight:700; color:#1e3a8a;">🎓 ข้อมูลสำหรับรับเกียรติบัตร (ข้อมูลจำเป็น)</h2>
<p style="color: #4b5563; font-size:0.9rem; margin-top:4px;">กรุณาระบุชื่อ-นามสกุลจริง และอีเมลมหาวิทยาลัยตาปี หรือ Gmail เพื่อระบบจะทำการส่งไฟล์เกียรติบัตรผ่านทางอีเมลโดยอัตโนมัติ</p>
</div>
<div class="survey-question" style="margin-top:16px;">
<div class="q-label" style="font-weight:700;">
<span>ชื่อ-นามสกุลจริง (ภาษาไทย เช่น นายสมชาย ใจดี)</span>
<span class="required">*</span>
</div>
<input type="text" class="form-input" id="respondentName" placeholder="กรอกชื่อ-นามสกุลจริง เช่น นายสมชาย ใจดี" required style="width: 100%; max-width: 500px; margin-top: 8px;">
</div>
<div class="survey-question" style="margin-top:16px;">
<div class="q-label" style="font-weight:700;">
<span>อีเมลสำหรับรับเกียรติบัตร (มหาวิทยาลัยตาปี หรือ Gmail)</span>
<span class="required">*</span>
</div>
<input type="email" class="form-input" id="respondentEmail" placeholder="เช่น name@gmail.com หรือ 651234567@student.tapee.ac.th" required
pattern="[a-zA-Z0-9._%+-]+@((student\\.)?tapee\\.ac\\.th|gmail\\.com|gmil\\.com)"
title="กรุณาใช้อีเมลมหาวิทยาลัยตาปี หรือ Gmail เท่านั้น"
style="width: 100%; max-width: 500px; margin-top: 8px;">
</div>
</div>
` : ''}
`;
(currentSurvey.sections || []).forEach(section => {
const cleanSectionTitle = section.title.replace(/^ส่วนที่\s*[\d๑-๙]+\s*/, '').replace(/^\s*[\d๑-๙]+[\.\)\s\-:\u00A0]*\s*/, '');
html += `
<div class="survey-section">
<div class="survey-section-header">
<h2>${escapeHtml(cleanSectionTitle)}</h2>
${section.description ? `<p>${escapeHtml(section.description)}</p>` : ''}
</div>
`;
// Render headings and their questions
(section.headings || []).forEach(heading => {
const cleanHeadingTitle = heading.title.replace(/^\s*[\d๑-๙]+[\.\)\s\-:\u00A0]*\s*/, '');
html += `
<div class="survey-heading" style="margin:24px 0 16px; padding:16px 20px; background:linear-gradient(135deg, rgba(37,99,235,0.06), rgba(37,99,235,0.10)); border-left:4px solid var(--primary-color, #2563eb); border-radius:0 12px 12px 0;">
<h3 style="margin:0; font-size:1.1rem; font-weight:700; color:#1e3a8a;">📑 ${escapeHtml(cleanHeadingTitle)}</h3>
${heading.description ? `<p style="margin:4px 0 0; font-size:0.9rem; color:#475569;">${escapeHtml(heading.description)}</p>` : ''}
</div>
`;
(heading.questions || []).forEach(q => {
html += renderQuestion(q);
});
});
// Render loose questions (not in any heading)
(section.questions || []).forEach(q => {
html += renderQuestion(q);
});
html += `</div>`;
});
html += `
<div class="text-center mt-32">
<button type="submit" id="submitBtn" class="btn btn-primary btn-lg" style="min-width:200px;">
📤 ส่งแบบสอบถาม
</button>
</div>
</form>
`;
container.innerHTML = html;
}
function renderQuestion(q) {
const cleanText = q.question_text.replace(/^\s*[\d๑-๙]+[\.\)\s\-:\u00A0]*\s*/, '');
let html = `
<div class="survey-question">
<div class="q-label">
<span>${escapeHtml(cleanText)}</span>
${q.is_required ? '<span class="required">*</span>' : ''}
</div>
`;
if (q.description) {
html += `<p style="font-size:0.85rem; color:#000000; margin:-4px 0 10px 0;">${escapeHtml(q.description)}</p>`;
}
if (q.question_type === 'radio') {
if (q.options && q.options.length > 0) {
html += `<div class="form-radio-group" style="flex-direction:column; align-items:flex-start;">`;
q.options.forEach(opt => {
html += `
<label class="radio-option" style="width:100%; border:none; padding:8px 0;">
<input type="radio" name="q_${q.id}" value="${escapeHtml(opt)}" ${q.is_required ? 'required' : ''}>
<span>${escapeHtml(opt)}</span>
</label>
`;
});
html += `</div>`;
} else {
html += `<div class="rating-scale">`;
const labels = ['น้อยที่สุด', 'น้อย', 'ปานกลาง', 'มาก', 'มากที่สุด'];
for (let i = 1; i <= 5; i++) {
html += `
<label>
<input type="radio" name="q_${q.id}" value="${i}" ${q.is_required ? 'required' : ''}>
<span class="rating-number">${i}</span>
<span class="rating-label">${labels[i-1]}</span>
</label>
`;
}
html += `</div>`;
}
} else if (q.question_type === 'text') {
html += `<textarea class="form-input" name="q_${q.id}" placeholder="กรอกความคิดเห็น..." rows="3" ${q.is_required ? 'required' : ''}></textarea>`;
} else if (q.question_type === 'dropdown') {
const options = q.options || [];
html += `<select class="form-input" name="q_${q.id}" ${q.is_required ? 'required' : ''}>`;
html += `<option value="">-- กรุณาเลือก --</option>`;
options.forEach(opt => {
const val = typeof opt === 'object' ? opt.value : opt;
const label = typeof opt === 'object' ? opt.label : opt;
html += `<option value="${escapeHtml(val)}">${escapeHtml(label)}</option>`;
});
html += `</select>`;
} else if (q.question_type === 'checkbox') {
const options = q.options || [];
html += `<div class="form-checkbox-group">`;
options.forEach((opt, oi) => {
const val = typeof opt === 'object' ? opt.value : opt;
const label = typeof opt === 'object' ? opt.label : opt;
html += `
<label class="checkbox-option">
<input type="checkbox" name="q_${q.id}_${oi}" value="${escapeHtml(val)}">
<span>${escapeHtml(label)}</span>
</label>
`;
});
html += `</div>`;
}
html += `</div>`;
return html;
}
// Collect all questions flat for submission
function getAllQuestions() {
const questions = [];
(currentSurvey.sections || []).forEach(section => {
(section.headings || []).forEach(heading => {
(heading.questions || []).forEach(q => questions.push(q));
});
(section.questions || []).forEach(q => questions.push(q));
});
return questions;
}
async function submitSurveyResponse(e) {
e.preventDefault();
const btn = document.getElementById('submitBtn');
btn.disabled = true;
btn.textContent = 'กำลังส่ง...';
const form = document.getElementById('surveyResponseForm');
const answers = [];
const allQuestions = getAllQuestions();
allQuestions.forEach(q => {
if (q.question_type === 'checkbox') {
const values = [];
form.querySelectorAll(`[name^="q_${q.id}_"]`).forEach(cb => {
if (cb.checked) values.push(cb.value);
});
answers.push({ question_id: q.id, value: values.join(', ') });
} else {
const el = form.querySelector(`[name="q_${q.id}"]`);
if (el) {
if (el.type === 'radio') {
const checked = form.querySelector(`[name="q_${q.id}"]:checked`);
answers.push({ question_id: q.id, value: checked ? checked.value : '' });
} else {
answers.push({ question_id: q.id, value: el.value });
}
}
}
});
// Get respondent information
const nameEl = document.getElementById('respondentName');
const emailEl = document.getElementById('respondentEmail');
const respondentName = nameEl ? nameEl.value.trim() : '';
const respondentEmail = emailEl ? emailEl.value.trim() : '';
const params = new URLSearchParams(window.location.search);
try {
const basePath = window.location.pathname.includes('/survey') ? '/survey' : '';
const res = await fetch(`${basePath}/api/responses.php?action=submit`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
survey_link: params.get('link'),
answers: answers,
respondent_info: {
name: respondentName,
email: respondentEmail
}
})
});
const data = await res.json();
if (data.success) {
document.getElementById('surveyContent').innerHTML = `
<div class="success-page" style="min-height:auto;padding:60px 20px;">
<div style="text-align:center;">
<img src="pic/logo.png" alt="TPU Logo" style="display: block; margin-left: auto; margin-right: auto; margin-bottom: 24px; height: 80px; width: auto;">
<div class="success-icon">✓</div>
<h2 style="font-size:24px;margin-bottom:12px;">ส่งแบบสอบถามสำเร็จ!</h2>
<p class="text-muted">ขอบคุณที่สละเวลาตอบแบบสอบถาม</p>
</div>
</div>
`;
} else {
throw new Error(data.error || 'เกิดข้อผิดพลาด');
}
} catch (err) {
alert('เกิดข้อผิดพลาด: ' + err.message);
btn.disabled = false;
btn.textContent = '📤 ส่งแบบสอบถาม';
}
}
function escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
document.addEventListener('DOMContentLoaded', initSurvey);