Fix inline item editing never activating on details pages
The script IIFE was reading window.inlineItemEdit at load time, before the inline <script> block in @section Scripts had executed to set it. Config read moved inside DOMContentLoaded so it fires after all inline scripts in the section have run, regardless of src vs. inline order. cfg is now passed as a parameter to makeEditable and attachListeners instead of being captured from the outer IIFE scope. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,13 +2,11 @@
|
||||
/// Shared inline-edit behaviour for quote, job, and invoice item rows.
|
||||
/// Activated when the page sets window.inlineItemEdit = { patchUrl, canEdit, totals }.
|
||||
/// totals: { subtotal, tax, total, finalPrice, balance } — CSS selectors, any subset.
|
||||
/// Config is read inside DOMContentLoaded so script load order vs. config assignment doesn't matter.
|
||||
/// </summary>
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const cfg = window.inlineItemEdit;
|
||||
if (!cfg || !cfg.canEdit) return;
|
||||
|
||||
function fmt(val) {
|
||||
return val.toLocaleString('en-US', { style: 'currency', currency: 'USD' });
|
||||
}
|
||||
@@ -26,7 +24,7 @@
|
||||
setTimeout(() => el.remove(), 4000);
|
||||
}
|
||||
|
||||
function updateTotals(data) {
|
||||
function updateTotals(cfg, data) {
|
||||
const t = cfg.totals || {};
|
||||
[
|
||||
[t.subtotal, data.subtotal],
|
||||
@@ -41,7 +39,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
function makeEditable(span) {
|
||||
function attachListeners(cfg, span) {
|
||||
span.style.cursor = 'text';
|
||||
span.title = 'Click to edit';
|
||||
span.classList.add('inline-editable');
|
||||
span.addEventListener('click', () => makeEditable(cfg, span), { once: true });
|
||||
}
|
||||
|
||||
function makeEditable(cfg, span) {
|
||||
const field = span.dataset.inlineField;
|
||||
const row = span.closest('tr[data-item-id]');
|
||||
if (!row) return;
|
||||
@@ -73,7 +78,7 @@
|
||||
|
||||
function revert() {
|
||||
span.innerHTML = savedHTML;
|
||||
attachListeners(span);
|
||||
attachListeners(cfg, span);
|
||||
}
|
||||
|
||||
async function commit() {
|
||||
@@ -136,10 +141,10 @@
|
||||
if (totalCell) totalCell.textContent = fmt(data.lineTotal);
|
||||
|
||||
// Update document-level totals
|
||||
updateTotals(data);
|
||||
updateTotals(cfg, data);
|
||||
|
||||
// Re-attach click listener for next edit
|
||||
attachListeners(span);
|
||||
attachListeners(cfg, span);
|
||||
|
||||
} catch {
|
||||
showError('Could not save — check your connection and try again.');
|
||||
@@ -154,14 +159,11 @@
|
||||
});
|
||||
}
|
||||
|
||||
function attachListeners(span) {
|
||||
span.style.cursor = 'text';
|
||||
span.title = 'Click to edit';
|
||||
span.classList.add('inline-editable');
|
||||
span.addEventListener('click', () => makeEditable(span), { once: true });
|
||||
}
|
||||
|
||||
// Read config inside DOMContentLoaded — by then the inline <script> that sets
|
||||
// window.inlineItemEdit has already executed regardless of script load order.
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
document.querySelectorAll('[data-inline-field]').forEach(attachListeners);
|
||||
const cfg = window.inlineItemEdit;
|
||||
if (!cfg || !cfg.canEdit) return;
|
||||
document.querySelectorAll('[data-inline-field]').forEach(span => attachListeners(cfg, span));
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user