Qualitative Data Excerpt Log

Qualitative Data Excerpt Log

Logged Excerpts (Editable)

Add excerpts using the "Entry Configuration" tab to populate this log.

Add New Data Excerpt

Add excerpts using the "Entry Configuration" tab to populate this log.

`; return; } logEntries.forEach(entry => { dashboardList.appendChild(createDashboardItem(entry)); }); // Setup listeners for newly created elements setupDashboardListeners(); } /** * Creates an editable item card for the dashboard */ function createDashboardItem(entry) { const card = document.createElement("div"); card.className = "qdel-entry-card"; card.dataset.id = entry.id; // Card structure with editable fields card.innerHTML = `
`; return card; } /** * Attaches listeners to the dashboard elements */ function setupDashboardListeners() { if (!dashboardList) return; // Listen for all input/change events to update state dashboardList.querySelectorAll('input, textarea').forEach(element => { element.addEventListener('change', handleDashboardUpdate); element.addEventListener('input', handleDashboardUpdate); }); // Listen for removal clicks (delegation) dashboardList.querySelectorAll('button[data-action="remove"]').forEach(button => { button.addEventListener('click', handleDashboardRemove); }); } /** * Updates the master `logEntries` array when dashboard fields change */ function handleDashboardUpdate(e) { const card = e.target.closest(".qdel-entry-card"); if (!card) return; const entryId = card.dataset.id; const entry = logEntries.find(e => e.id === entryId); if (!entry) return; const field = e.target.dataset.field; if (!field) return; // Update the specific field in the master array entry[field] = e.target.value; // Special case: Ensure ID is uppercase if (field === 'code') entry.code = entry.code.toUpperCase(); } /** * Handles removing an item directly from the dashboard */ function handleDashboardRemove(e) { const card = e.target.closest(".qdel-entry-card"); if (card) { // Remove from master array logEntries = logEntries.filter(entry => entry.id !== card.dataset.id); renderDashboard(); // Re-render dashboard } } /** * Generates a PDF report from the dashboard data */ function downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF.autoTable === 'undefined') { alert("Error: PDF libraries could not be loaded. Please try again."); return; } if (logEntries.length === 0) { alert("Log is empty. Please add entries first."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF("l", "pt", "a4"); // Landscape for more space const margin = 40; let yPos = margin; const tableHead = [["ID", "Source", "Excerpt Text", "Theme/Code", "Analyst Notes"]]; const tableBody = []; // Get data from the *current* master state (which reflects dashboard edits) logEntries.forEach((entry) => { tableBody.push([ entry.code, entry.source, entry.excerpt, entry.theme, entry.notes ]); }); doc.setFontSize(18); doc.text("Qualitative Data Excerpt Log", margin, yPos); yPos += 30; doc.autoTable({ startY: yPos, head: tableHead, body: tableBody, theme: 'striped', headStyles: { fillColor: [0, 115, 230], // Blue textColor: [255, 255, 255], fontSize: 10 }, columnStyles: { 0: { cellWidth: 60 }, // ID 1: { cellWidth: 70 }, // Source 2: { cellWidth: 200 }, // Excerpt (widest) 3: { cellWidth: 70 }, // Theme 4: { cellWidth: 'auto' }, // Notes (rest of space) }, styles: { fontSize: 9, cellPadding: 3, overflow: 'linebreak' // Important for long text }, margin: { left: margin, right: margin } }); doc.save("Qualitative_Excerpt_Log.pdf"); } /** * Helper to escape HTML */ function escapeHTML(str) { if (!str) return ""; return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // --- 3. INITIALIZATION & EVENT LISTENERS --- // Tab Listeners tabButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); navButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); // Config Tab Listeners if (addEntryForm) { addEntryForm.addEventListener("submit", handleAddEntry); } // Dashboard Tab Listeners if (pdfBtn) { pdfBtn.addEventListener("click", downloadPDF); } // Load sample data logEntries = [ { id: 'entry-1', code: 'P01-Q05', source: 'Interview 1', excerpt: '“I think the biggest hurdle for adoption was just trust. People are used to the old system, and the new one felt too opaque, too much like a black box, even though it was technically more secure.”', theme: 'Trust/Adoption Barriers', notes: 'Participant is a senior manager; suggests internal communication failed to bridge the trust gap despite technical superiority.' }, { id: 'entry-2', code: 'FG2-T04', source: 'Focus Group 2', excerpt: 'Observed several participants nodding when Lisa mentioned the cost saving, but Jane immediately countered with the time loss. Conflict between efficiency and cost.', theme: 'Efficiency vs. Cost', notes: 'Non-verbal observation is key here. Note the quick shift from agreement to explicit disagreement in the discussion.' } ]; // Initial State renderDashboard(); showTab("qdel-tab-dashboard"); });
Scroll to Top