/** * Survey Preview Module * Provides real-time preview of survey questions as they are being built */ class SurveyPreview { constructor() { this.previewContainer = null; this.init(); } init() { document.addEventListener('DOMContentLoaded', () => { this.createPreviewPanel(); this.setupEventListeners(); }); } createPreviewPanel() { // Find the main container const mainContainer = document.querySelector('.container-fluid'); if (!mainContainer) return; // Create preview card const previewCard = document.createElement('div'); previewCard.className = 'card'; previewCard.id = 'survey-preview-card'; previewCard.style.marginTop = '20px'; previewCard.style.display = 'none'; // Hidden by default previewCard.innerHTML = `
Survey Preview

Add questions to see preview

`; // Add preview toggle button to header const headerTitle = document.querySelector('h2'); if (headerTitle) { const toggleBtn = document.createElement('button'); toggleBtn.type = 'button'; toggleBtn.className = 'btn btn-outline-primary ms-3'; toggleBtn.innerHTML = ' Preview'; toggleBtn.addEventListener('click', () => this.togglePreview()); headerTitle.parentNode.appendChild(toggleBtn); } // Insert preview card after main form const mainRow = document.querySelector('.row'); if (mainRow) { mainRow.parentNode.insertBefore(previewCard, mainRow.nextSibling); } this.previewContainer = previewCard; } setupEventListeners() { // Toggle preview button const toggleBtn = document.getElementById('toggle-preview'); if (toggleBtn) { toggleBtn.addEventListener('click', () => this.togglePreviewSize()); } // Close preview button const closeBtn = document.getElementById('close-preview'); if (closeBtn) { closeBtn.addEventListener('click', () => this.togglePreview()); } // Watch for form changes const form = document.getElementById('survey-template-form'); if (form) { const observer = new MutationObserver(() => { this.updatePreview(); }); observer.observe(form, { childList: true, subtree: true, attributes: true, attributeFilter: ['value', 'checked'] }); } // Listen for input changes document.addEventListener('input', (e) => { if (e.target.closest('#questions-container')) { this.updatePreview(); } }); document.addEventListener('change', (e) => { if (e.target.closest('#questions-container')) { this.updatePreview(); } }); } togglePreview() { if (!this.previewContainer) return; const isHidden = this.previewContainer.style.display === 'none'; this.previewContainer.style.display = isHidden ? 'block' : 'none'; if (isHidden) { this.updatePreview(); } } togglePreviewSize() { if (!this.previewContainer) return; const cardBody = this.previewContainer.querySelector('.card-body'); const isExpanded = cardBody.classList.contains('expanded'); if (isExpanded) { cardBody.classList.remove('expanded'); cardBody.style.maxHeight = '500px'; cardBody.style.overflowY = 'auto'; } else { cardBody.classList.add('expanded'); cardBody.style.maxHeight = 'none'; cardBody.style.overflow = 'visible'; } } updatePreview() { if (!this.previewContainer || this.previewContainer.style.display === 'none') { return; } const previewContent = document.getElementById('preview-content'); if (!previewContent) return; // Get survey name const nameInput = document.querySelector('input[name="name"]'); const name = nameInput ? nameInput.value : 'Untitled Survey'; // Get all questions const questionForms = document.querySelectorAll('.question-form:not([style*="display: none"])'); const questions = Array.from(questionForms).map(form => this.extractQuestionData(form)).filter(q => q); if (questions.length === 0) { previewContent.innerHTML = `

Add questions to see preview

`; return; } // Generate preview HTML let previewHTML = `

${this.escapeHtml(name)}

Preview - ${questions.length} question(s)

`; questions.forEach((q, index) => { previewHTML += this.renderQuestionPreview(q, index + 1); }); previewHTML += '
'; previewContent.innerHTML = previewHTML; } extractQuestionData(form) { const textInput = form.querySelector('input[name$="-text"]'); const textArInput = form.querySelector('input[name$="-text_ar"]'); const typeSelect = form.querySelector('select[name$="-question_type"]'); const requiredCheckbox = form.querySelector('input[name$="-is_required"]'); const choicesTextarea = form.querySelector('textarea[name$="-choices_json"]'); if (!textInput || !textInput.value.trim()) { return null; } const data = { text: textInput.value, text_ar: textArInput ? textArInput.value : '', type: typeSelect ? typeSelect.value : 'text', required: requiredCheckbox ? requiredCheckbox.checked : false, choices: [] }; if (choicesTextarea) { try { const choices = JSON.parse(choicesTextarea.value); if (Array.isArray(choices)) { data.choices = choices; } } catch (e) { // Invalid JSON, ignore } } return data; } renderQuestionPreview(question, number) { let questionHTML = `
Q${number}: ${this.escapeHtml(question.text)} ${question.required ? '*' : ''}
`; switch (question.type) { case 'text': questionHTML += ` `; break; case 'rating': questionHTML += `
${[1, 2, 3, 4, 5].map(n => ` `).join('')}
`; break; case 'single_choice': if (question.choices.length > 0) { questionHTML += '
'; question.choices.forEach(choice => { questionHTML += ` `; }); questionHTML += '
'; } else { questionHTML += '

No choices defined

'; } break; case 'multiple_choice': if (question.choices.length > 0) { questionHTML += '
'; question.choices.forEach(choice => { questionHTML += ` `; }); questionHTML += '
'; } else { questionHTML += '

No choices defined

'; } break; } questionHTML += '
'; return questionHTML; } escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } } // Initialize document.addEventListener('DOMContentLoaded', () => { window.surveyPreview = new SurveyPreview(); });