From 3ae6ce53bce40a521d7a336bb4ec03c7b1e9f649 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 23 Mar 2026 12:15:49 +0000 Subject: [PATCH] Enhance markup inserter with logging and auto-attach functionality for textareas --- atlas/static/atlas/js/markup_inserter.js | 30 +++++++- atlas/templates/atlas/case_form.html | 92 ++++++++++++------------ 2 files changed, 75 insertions(+), 47 deletions(-) diff --git a/atlas/static/atlas/js/markup_inserter.js b/atlas/static/atlas/js/markup_inserter.js index 7ab331bd..ce6529c4 100644 --- a/atlas/static/atlas/js/markup_inserter.js +++ b/atlas/static/atlas/js/markup_inserter.js @@ -1,5 +1,6 @@ // Simple markup inserter module (function(global){ + console.log('markup_inserter.js loaded'); function insertAtCursor(el, text){ if(!el) return; const start = el.selectionStart || 0; @@ -32,6 +33,7 @@ if(!textarea) return null; // avoid double attaching if(textarea._markupToolbarAttached) return null; + console.log('Attaching markup toolbar to textarea', textarea); const toolbar = createToolbar(); textarea.parentNode.insertBefore(toolbar, textarea); toolbar.querySelectorAll('.markup-insert-button').forEach(function(btn){ @@ -53,6 +55,7 @@ function initForNames(names){ if(!Array.isArray(names)) return; document.addEventListener('DOMContentLoaded', function(){ + console.log('markupInserter.initForNames DOMContentLoaded handler running for', names); names.forEach(function(name){ const el = document.querySelector('textarea[name="'+name+'"]'); if(el) attachToolbarToTextarea(el); @@ -70,23 +73,48 @@ // Auto-attach to placeholders rendered in HTMX responses or server-side includes. document.addEventListener('DOMContentLoaded', function(){ + console.log('markupInserter DOMContentLoaded auto-attach running'); + // Attach to explicit placeholders document.querySelectorAll('.markup-toolbar-placeholder').forEach(function(ph){ - // find next textarea sibling let ta = ph.nextElementSibling; if(ta && ta.tagName === 'TEXTAREA') attachToolbarToTextarea(ta); }); + + // Also auto-init for common case textarea names to cover full-page forms + try{ initForNames(['description','history','discussion','report','notes']); }catch(e){} }); document.addEventListener('htmx:afterSwap', function(evt){ + console.log('markupInserter htmx:afterSwap event', evt && evt.detail && evt.detail.target); try{ const target = evt.detail && evt.detail.target ? evt.detail.target : document; (target.querySelectorAll ? target : document).querySelectorAll('.markup-toolbar-placeholder').forEach(function(ph){ let ta = ph.nextElementSibling; if(ta && ta.tagName === 'TEXTAREA') attachToolbarToTextarea(ta); }); + + // Also attach to any textareas within the swapped target that match our common names + var ctx = evt.detail && evt.detail.target ? evt.detail.target : document; + ['description','history','discussion','report','notes'].forEach(function(name){ + ctx.querySelectorAll && ctx.querySelectorAll('textarea[name="'+name+'"]') && ctx.querySelectorAll('textarea[name="'+name+'"]').forEach(function(ta){ attachToolbarToTextarea(ta); }); + }); }catch(e){/* ignore */} }); + // Fallback: attach toolbar when a textarea receives focus (covers dynamically created editors) + document.addEventListener('focusin', function(e){ + console.log('markupInserter focusin event for', e && e.target); + try{ + var el = e.target; + if(!el || el.tagName !== 'TEXTAREA') return; + // Attach for common names or if a placeholder is present + var name = el.getAttribute('name') || ''; + if(['description','history','discussion','report','notes'].includes(name) || (el.previousElementSibling && el.previousElementSibling.classList && el.previousElementSibling.classList.contains('markup-toolbar-placeholder'))){ + attachToolbarToTextarea(el); + } + }catch(err){/* ignore */} + }, true); + // Expose API global.markupInserter = { attachToolbarToTextarea: attachToolbarToTextarea, diff --git a/atlas/templates/atlas/case_form.html b/atlas/templates/atlas/case_form.html index 343659cb..546d6979 100755 --- a/atlas/templates/atlas/case_form.html +++ b/atlas/templates/atlas/case_form.html @@ -146,58 +146,58 @@ -
- -
- -
-
-
    - {% for form in casedifferential_formset %} -
  1. - {{form.non_field_errors}} - {{form.errors}} - {{ form | crispy}} -
  2. - {% endfor %} -
+
+ +
+ +
+
+
    + {% for form in casedifferential_formset %} +
  1. + {{form.non_field_errors}} + {{form.errors}} + {{ form | crispy}} +
  2. + {% endfor %} +
+
+ {{ casedifferential_formset.management_form | crispy }} +
- {{ casedifferential_formset.management_form | crispy }}
-
-
-
- -
- -
-
-
    - {% for form in caseresource_formset %} -
  1. - {{form.non_field_errors}} - {{form.errors}} - {{ form | crispy}} -
  2. - {% endfor %} -
+
+ +
+ +
+
+
    + {% for form in caseresource_formset %} +
  1. + {{form.non_field_errors}} + {{form.errors}} + {{ form | crispy}} +
  2. + {% endfor %} +
+
+ {{ caseresource_formset.management_form | crispy}} +
- {{ caseresource_formset.management_form | crispy}}
-
-