294 lines
13 KiB
JavaScript
294 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 = getAppBasePath();
|
|
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 => {
|
|
html += `
|
|
<div class="survey-section">
|
|
<div class="survey-section-header">
|
|
<h2>${escapeHtml(section.title)}</h2>
|
|
${section.description ? `<p>${escapeHtml(section.description)}</p>` : ''}
|
|
</div>
|
|
`;
|
|
|
|
// Render headings and their questions
|
|
(section.headings || []).forEach(heading => {
|
|
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(heading.title)}</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) {
|
|
let html = `
|
|
<div class="survey-question">
|
|
<div class="q-label">
|
|
<span>${escapeHtml(q.question_text)}</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 = getAppBasePath();
|
|
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);
|