Fix Google Form Grid parser, survey display, and instant copy link button

This commit is contained in:
pongpon pitisuk
2026-09-12 15:08:23 +07:00
parent e01d01464a
commit 0e09259c9d
5 changed files with 188 additions and 65 deletions
+7 -16
View File
@@ -809,9 +809,9 @@ async function generateLink(id) {
<div class="qr-link-container">
<div class="qr-link-section">
<div class="qr-link-label">🔗 ลิงก์แบบสอบถาม</div>
<div class="link-display">
<span class="flex-1" id="surveyLinkText">${fullUrl}</span>
<button class="copy-btn" onclick="copyLink()">📋 คัดลอก</button>
<div class="link-display" onclick="copyLink(this.querySelector('.copy-btn'))" style="cursor:pointer;" title="คลิกเพื่อคัดลอกลิงก์">
<span class="flex-1 select-all" id="surveyLinkText">${fullUrl}</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyLink(this)">📋 คัดลอก</button>
</div>
</div>
<div class="qr-code-section">
@@ -849,20 +849,11 @@ async function generateLink(id) {
}
}
function copyLink() {
const text = document.getElementById('surveyLinkText')?.textContent;
function copyLink(btnEl) {
const text = document.getElementById('surveyLinkText')?.textContent?.trim();
if (text) {
navigator.clipboard.writeText(text).then(() => {
Toast.success('คัดลอกลิงก์แล้ว');
}).catch(() => {
const ta = document.createElement('textarea');
ta.value = text;
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
ta.remove();
Toast.success('คัดลอกลิงก์แล้ว');
});
const btn = btnEl || document.querySelector('.link-display .copy-btn');
copyTextToClipboard(text, btn);
}
}
+57
View File
@@ -43,6 +43,63 @@ const API = {
}
};
// ============================================================
// Universal Clipboard Helper (HTTP & HTTPS compatible)
// ============================================================
function copyTextToClipboard(text, btnElement) {
if (!text) return;
const showSuccess = () => {
if (typeof Toast !== 'undefined') Toast.success('คัดลอกลิงก์สำเร็จแล้ว!');
if (btnElement) {
const origHtml = btnElement.innerHTML;
btnElement.innerHTML = '✅ คัดลอกแล้ว!';
btnElement.style.backgroundColor = '#16a34a';
btnElement.style.color = '#ffffff';
setTimeout(() => {
btnElement.innerHTML = origHtml;
btnElement.style.backgroundColor = '';
btnElement.style.color = '';
}, 2000);
}
};
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(text).then(showSuccess).catch(() => fallbackCopy(text, showSuccess));
} else {
fallbackCopy(text, showSuccess);
}
}
function fallbackCopy(text, callback) {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.top = '0';
textArea.style.left = '0';
textArea.style.width = '2em';
textArea.style.height = '2em';
textArea.style.padding = '0';
textArea.style.border = 'none';
textArea.style.outline = 'none';
textArea.style.boxShadow = 'none';
textArea.style.background = 'transparent';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
const successful = document.execCommand('copy');
if (successful && callback) {
callback();
} else if (!successful && typeof Toast !== 'undefined') {
Toast.error('กรุณากดคัดลอกด้วยตนเอง');
}
} catch (err) {
if (typeof Toast !== 'undefined') Toast.error('ไม่สามารถคัดลอกได้');
}
document.body.removeChild(textArea);
}
// ============================================================
// Auth State
// ============================================================
+3 -6
View File
@@ -83,21 +83,19 @@ function renderSurvey() {
(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>
<h2>${escapeHtml(section.title)}</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>
<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>
`;
@@ -127,11 +125,10 @@ function renderSurvey() {
}
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>
<span>${escapeHtml(q.question_text)}</span>
${q.is_required ? '<span class="required">*</span>' : ''}
</div>
`;
+7 -9
View File
@@ -385,9 +385,9 @@ async function teacherGenerateLink(id) {
<div class="qr-link-container">
<div class="qr-link-section">
<div class="qr-link-label">🔗 ลิงก์แบบสอบถาม</div>
<div class="link-display">
<span class="flex-1" id="surveyLinkText">${fullUrl}</span>
<button class="copy-btn" onclick="copyTeacherLink()">📋 คัดลอก</button>
<div class="link-display" onclick="copyTeacherLink(this.querySelector('.copy-btn'))" style="cursor:pointer;" title="คลิกเพื่อคัดลอกลิงก์">
<span class="flex-1 select-all" id="surveyLinkText">${fullUrl}</span>
<button class="copy-btn" onclick="event.stopPropagation(); copyTeacherLink(this)">📋 คัดลอก</button>
</div>
</div>
<div class="qr-code-section">
@@ -425,13 +425,11 @@ async function teacherGenerateLink(id) {
}
}
function copyTeacherLink() {
const text = document.getElementById('surveyLinkText')?.textContent;
function copyTeacherLink(btnEl) {
const text = document.getElementById('surveyLinkText')?.textContent?.trim();
if (text) {
navigator.clipboard.writeText(text).then(() => Toast.success('คัดลอกแล้ว')).catch(() => {
const ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove();
Toast.success('คัดลอกแล้ว');
});
const btn = btnEl || document.querySelector('.link-display .copy-btn');
copyTextToClipboard(text, btn);
}
}