Fix module init: defer all tab scripts until component HTML is loaded
All JS modules were running immediately (IIFE/DOMContentLoaded) but tab HTML is lazy-loaded from /components/*.html, causing null errors on every addEventListener call. Each module now listens for tabChanged with its tab name and initializes once after the DOM is ready. Also: quiz question/explanation boxes changed to textarea for multi-line support; quiz display uses sanitizeHtml() so formatted text (bold, lists, etc.) renders correctly.
This commit is contained in:
parent
b933b449a8
commit
6c0c911dbd
11 changed files with 56 additions and 8 deletions
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'chart' || _inited) return;
|
||||
_inited = true;
|
||||
var visitsContainer = document.getElementById('cr-visits-container');
|
||||
var addVisitBtn = document.getElementById('cr-add-visit');
|
||||
var labsContainer = document.getElementById('cr-labs-container');
|
||||
|
|
@ -165,4 +169,5 @@
|
|||
});
|
||||
|
||||
console.log('✅ Chart Review module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'hospital' || _inited) return;
|
||||
_inited = true;
|
||||
var notesContainer = document.getElementById('hc-notes-container');
|
||||
var addNoteBtn = document.getElementById('hc-add-note');
|
||||
var labsContainer = document.getElementById('hc-labs-container');
|
||||
|
|
@ -202,4 +206,5 @@
|
|||
});
|
||||
|
||||
console.log('✅ Hospital Course module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@
|
|||
'<span class="lh-quiz-q-num">Q' + (idx + 1) + '</span>' +
|
||||
'<span class="lh-quiz-q-type">' + typeLabel + '</span>' +
|
||||
'</div>' +
|
||||
'<p class="lh-quiz-q-text">' + esc(q.question_text) + '</p>' +
|
||||
'<p class="lh-quiz-q-text">' + sanitizeHtml(q.question_text) + '</p>' +
|
||||
'<div class="lh-quiz-options">' + optionsHtml + '</div>' +
|
||||
'</div>';
|
||||
}).join('');
|
||||
|
|
@ -359,11 +359,11 @@
|
|||
explHtml += '<div class="lh-expl lh-expl-correct"><strong>Correct answer:</strong> ' + esc(r.correctOptionText) + '</div>';
|
||||
}
|
||||
if (r.generalExplanation) {
|
||||
explHtml += '<div class="lh-expl lh-expl-general"><strong>Explanation:</strong> ' + esc(r.generalExplanation) + '</div>';
|
||||
explHtml += '<div class="lh-expl lh-expl-general"><strong>Explanation:</strong> ' + sanitizeHtml(r.generalExplanation) + '</div>';
|
||||
}
|
||||
|
||||
return '<div class="lh-result-item">' +
|
||||
'<div class="lh-result-header">' + icon + ' <strong>Q' + (idx + 1) + ':</strong> ' + esc(r.questionText) + '</div>' +
|
||||
'<div class="lh-result-header">' + icon + ' <strong>Q' + (idx + 1) + ':</strong> ' + sanitizeHtml(r.questionText) + '</div>' +
|
||||
explHtml +
|
||||
'</div>';
|
||||
}).join('');
|
||||
|
|
@ -797,7 +797,7 @@
|
|||
'</div>' +
|
||||
'<button class="btn-sm btn-ghost lh-rm-question" style="padding:2px 8px;font-size:12px;color:var(--red);"><i class="fas fa-trash"></i></button>' +
|
||||
'</div>' +
|
||||
'<input type="text" class="lh-q-text" placeholder="Enter question text..." value="' + esc(existingQ ? existingQ.question_text : '') + '" style="width:100%;font-size:14px;font-weight:500;padding:10px;border:1.5px solid var(--g300);border-radius:8px;box-sizing:border-box;margin-bottom:8px;">' +
|
||||
'<textarea class="lh-q-text" placeholder="Enter question text..." rows="3" style="width:100%;font-size:14px;font-weight:500;padding:10px;border:1.5px solid var(--g300);border-radius:8px;box-sizing:border-box;margin-bottom:8px;resize:vertical;font-family:inherit;"></textarea>' +
|
||||
'<div style="margin-bottom:8px;">' +
|
||||
'<label style="font-size:11px;font-weight:600;color:var(--g500);text-transform:uppercase;letter-spacing:0.3px;display:block;margin-bottom:4px;">Answer Options <span style="color:var(--green);">(check the correct answer)</span></label>' +
|
||||
'</div>' +
|
||||
|
|
@ -805,11 +805,15 @@
|
|||
'<button class="btn-sm btn-ghost lh-add-option" style="margin-top:6px;font-size:12px;"><i class="fas fa-plus"></i> Add Option</button>' +
|
||||
'<div style="margin-top:8px;">' +
|
||||
'<label style="font-size:11px;font-weight:600;color:var(--g500);display:block;margin-bottom:3px;">Explanation (shown after answering)</label>' +
|
||||
'<input type="text" class="lh-q-explanation" placeholder="Explain the correct answer..." value="' + esc(existingQ ? existingQ.explanation || '' : '') + '" style="width:100%;font-size:12px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;">' +
|
||||
'<textarea class="lh-q-explanation" placeholder="Explain the correct answer..." rows="2" style="width:100%;font-size:12px;padding:6px 10px;border:1px solid var(--g300);border-radius:6px;box-sizing:border-box;resize:vertical;font-family:inherit;"></textarea>' +
|
||||
'</div>';
|
||||
|
||||
container.appendChild(block);
|
||||
|
||||
// Set textarea values after insertion (can't use value="" attr on textarea)
|
||||
block.querySelector('.lh-q-text').value = existingQ ? existingQ.question_text || '' : '';
|
||||
block.querySelector('.lh-q-explanation').value = existingQ ? existingQ.explanation || '' : '';
|
||||
|
||||
var optList = block.querySelector('.lh-options-list');
|
||||
if (existingQ && existingQ.options && existingQ.options.length > 0) {
|
||||
existingQ.options.forEach(function(opt) { addOptionRow(optList, opt); });
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'encounter' || _inited) return;
|
||||
_inited = true;
|
||||
var recordBtn = document.getElementById('enc-record-btn');
|
||||
var pauseBtn = document.getElementById('enc-pause-btn');
|
||||
var indicator = document.getElementById('enc-recording-indicator');
|
||||
|
|
@ -152,4 +156,5 @@
|
|||
}
|
||||
|
||||
console.log('✅ Encounter module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'wellvisit' || _inited) return;
|
||||
_inited = true;
|
||||
var ageSelect = document.getElementById('ms-age-group');
|
||||
var checklist = document.getElementById('milestone-checklist');
|
||||
var actionsBar = document.getElementById('milestone-actions');
|
||||
|
|
@ -181,4 +185,5 @@
|
|||
});
|
||||
|
||||
console.log('✅ Milestones module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'settings' || _inited) return;
|
||||
_inited = true;
|
||||
function loadNextcloudStatus() {
|
||||
fetch('/api/auth/me', { headers: getAuthHeaders() })
|
||||
.then(function(r) { return r.json(); })
|
||||
|
|
@ -51,4 +55,5 @@
|
|||
});
|
||||
|
||||
console.log('✅ Nextcloud module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -988,7 +988,10 @@
|
|||
}
|
||||
|
||||
// ── Init on DOM ready ────────────────────────────────────────────────────
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'wellvisit' || _inited) return;
|
||||
_inited = true;
|
||||
initShadess();
|
||||
initShadessRecording();
|
||||
initWvRecording();
|
||||
|
|
|
|||
|
|
@ -411,7 +411,10 @@
|
|||
}
|
||||
|
||||
// ── Init ──────────────────────────────────────────────────────────────────
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'sickvisit' || _inited) return;
|
||||
_inited = true;
|
||||
initRecording();
|
||||
populateAddDropdowns();
|
||||
renderRosPe();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'soap' || _inited) return;
|
||||
_inited = true;
|
||||
var recordBtn = document.getElementById('soap-record-btn');
|
||||
var indicator = document.getElementById('soap-recording-indicator');
|
||||
var timerEl = document.getElementById('soap-timer');
|
||||
|
|
@ -96,4 +100,5 @@
|
|||
document.getElementById('soap-shorten-btn').addEventListener('click', function() { shortenDocument('soap-text'); });
|
||||
|
||||
console.log('✅ SOAP module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
(function() {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'dictation' || _inited) return;
|
||||
_inited = true;
|
||||
var recordBtn = document.getElementById('dict-record-btn');
|
||||
var pauseBtn = document.getElementById('dict-pause-btn');
|
||||
var indicator = document.getElementById('dict-recording-indicator');
|
||||
|
|
@ -162,4 +166,5 @@
|
|||
}
|
||||
|
||||
console.log('✅ Dictation module loaded');
|
||||
});
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -650,7 +650,10 @@
|
|||
}
|
||||
|
||||
// ─── Wire up ───────────────────────────────────────────────────────────────
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var _inited = false;
|
||||
document.addEventListener('tabChanged', function(e) {
|
||||
if (e.detail.tab !== 'wellvisit' || _inited) return;
|
||||
_inited = true;
|
||||
init();
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue