Forums / Managing Customers and Orders / Order Comments Status/Update Boilerplate

Order Comments Status/Update Boilerplate

Views: 71,332

Results 81 to 83 of 83
17 Jan 2026, 5:37 AM
#81
carbonless avatar

carbonless

Zen Follower

Join Date:
Jan 2007
Location:
Illinois, USA
Posts:
329
Plugin Contributions:
0

Order Comments Status/Update Boilerplate

I got Boiler plate to work on 2.1 editing the orders.php file

  • CKEditor 5’s visible editor is not updating at all because CKEditor 5 ignores direct DOM updates (innerHTML) and will immediately revert to its internal model.

  • The only reliable way to update CKEditor 5 is via its editor instance API: editor.setData(...).
    So I rebuilt the handler to find the CKEditor 5 editor instance (even if Zen Cart stores it in a non-obvious place) and then insert using:

  • editor.getData() + editor.setData(current + comment)

NTO: building a better network thru collaboration
www.needtoorder.com | www.coffeewitheinstein.com

22 Jan 2026, 1:23 PM
#82
apollowilcox avatar

apollowilcox

Zen Follower

Join Date:
Sep 2014
Location:
Indiana
Posts:
123
Plugin Contributions:
0

Re: Order Comments Status/Update Boilerplate

Thanks Carbonless.

We really miss using this plug-in and would love to see it back in action. Is your comment addressing that fact that it will not function when the ZC editor is using CKEditor vs Plain text?

If so, can you help me with where you placed that line - or what line you replaced?

Thank you.

23 Jan 2026, 7:04 AM
#83
carbonless avatar

carbonless

Zen Follower

Join Date:
Jan 2007
Location:
Illinois, USA
Posts:
329
Plugin Contributions:
0

Re: Order Comments Status/Update Boilerplate

I edited the orders.php file. THE CK EDITOR was not updating because CKEditor 5 ignores direct DOM updates and was immediately reverting to the internal model.
So I rebuilt the handler to find the CKEditor 5 editor instance and then insert using:

  • editor.getData() + editor.setData(current + comment)

That is the method CKEditor 5 actually honors.

Inject near the top of orders.php after $show_including_tax is set (or anywhere before the form is rendered).
/* ===== BOF: Predefined Comments (Zen4All / Boilerplate) ===== /
$z4a_predefined_comments = [];
if (defined('TABLE_ORDER_COMMENTS_CONTENT')) {
$z4a_predefined_comments_query = "SELECT comment_id, comment_title, comment_text
FROM " . TABLE_ORDER_COMMENTS_CONTENT . "
ORDER BY comment_title";
$z4a_predefined_comments = $db->Execute($z4a_predefined_comments_query);
}
/
===== EOF: Predefined Comments ===== */

Inject inside the status update form (near the comments textarea).
This version stores the comment body in each option’s data-comment attribute.
/* ===== BOF: Predefined Comments dropdown ===== */
if (isset($z4a_predefined_comments) && is_object($z4a_predefined_comments) && !$z4a_predefined_comments->EOF) {
echo '<div class="form-group" style="margin: 10px 0;">';
echo ' <label for="z4a_predefined_comments"><strong>' . (defined('ENTRY_PREDEFINED_COMMENTS') ? ENTRY_PREDEFINED_COMMENTS : 'Predefined Comments') . '</strong></label>';
echo ' <select id="z4a_predefined_comments" class="form-control" onchange="z4aInsertPredefinedComment(this)">';
echo ' <option value="">' . (defined('TEXT_SELECT_COMMENT') ? TEXT_SELECT_COMMENT : 'Select a comment...') . '</option>';

while (!$z4a_predefined_comments->EOF) {
$commentTitle = zen_output_string_protected($z4a_predefined_comments->fields['comment_title']);
$commentText = $z4a_predefined_comments->fields['comment_text'];

// Escape for attribute safely
$commentTextAttr = htmlspecialchars($commentText, ENT_QUOTES, CHARSET);

echo '    <option value="' . (int)$z4a_predefined_comments->fields['comment_id'] . '" data-comment="' . $commentTextAttr . '">' . $commentTitle . '</option>';
$z4a_predefined_comments->MoveNext();

}

echo ' </select>';
echo '</div>';
}
/* ===== EOF: Predefined Comments dropdown ===== */

Inject once on the page (best placed near the bottom of orders.php, after the form exists, or in the header if you prefer).
This is the critical piece: it finds CKEditor 5’s editor instance and uses setData() so the UI updates correctly.

<script> /* ===== BOF: Predefined Comments insert (CKEditor 5 safe) ===== */ window.z4aInsertPredefinedComment = function(sel) { try { var opt = sel.options[sel.selectedIndex]; if (!opt) return; var html = opt.getAttribute('data-comment') || ''; if (!html.trim()) return; // breadcrumb for debugging (optional) window.__z4a_last_inserted = html.substring(0, 160); // locate textarea var ta = document.querySelector('textarea[name="comments"], #comments'); // Try to locate CKEditor 5 instance in the page // Common patterns: // - window.editor (single editor) // - window.editors (map) // - element.ckeditorInstance (some builds) var editor = null; if (window.editor && typeof window.editor.setData === 'function') { editor = window.editor; } else if (window.editors && typeof window.editors === 'object') { for (var k in window.editors) { if (window.editors[k] && typeof window.editors[k].setData === 'function') { editor = window.editors[k]; break; } } } // If we found CKEditor 5, update it properly if (editor && typeof editor.getData === 'function' && typeof editor.setData === 'function') { var current = editor.getData() || ''; editor.setData(current + html); // Keep textarea in sync for submit safety if (ta) ta.value = editor.getData(); return; } // Fallback: no editor instance found, just append to textarea if (ta) { ta.value = (ta.value || '') + html; } } catch (e) { // swallow to avoid breaking admin console.error(e); } }; /* ===== EOF: Predefined Comments insert ===== */ </script>

NTO: building a better network thru collaboration
www.needtoorder.com | www.coffeewitheinstein.com