Environment
- Bricksforge 4.0.0-beta.2 (also reproducible on 3.1.8.9)
- Bricks 2.4-rc / 2.3.12
- WordPress 7.1, PHP 8.4
- Rich Text field with “Style: WordPress” (TinyMCE), multi-step form
What happens
In a Pro Form containing both a Rich Text field (WordPress style) and a Repeater,
the Rich Text content is silently discarded if the user adds or removes a repeater
row after typing the text. The hidden transport input is emptied, so the field
arrives empty in $_POST and in the custom action. The editor itself still shows
the text, which makes the data loss easy to miss.
Steps to reproduce
- Build a multi-step Pro Form with a Rich Text field (Style: WordPress) and a Repeater.
- Type some text into the Rich Text field.
- Go to the repeater and click the “+” (or “-”) button to add/remove a row.
- Submit the form.
- The Rich Text value is empty. Console check before submitting:
document.querySelectorAll(‘input[data-type=“rich-text”]’).forEach(i => console.log(i.name, i.value))
→ empty string.
Typing into the editor again after step 3 restores the value, which is why the
issue looks intermittent.
Cause (bricksforge_elements.js)
handleRichText() copies the textarea value into the hidden input:
handleRichText(){
this.form.querySelectorAll(“.brf-rich-text-container”).forEach(e => {
let t = e.closest(“.form-group”).querySelector(“input[type=‘hidden’][data-type=‘rich-text’]”);
t && (t.value = e.value);
})
}
In WordPress/TinyMCE mode, “.brf-rich-text-container” is the textarea that TinyMCE
hides on init. TinyMCE only writes back to that textarea on editor.save() or on a
real form submit; neither happens here, because Bricksforge submits via AJAX and
never calls triggerSave()/save(). The textarea therefore stays permanently empty,
and handleRichText() overwrites the correctly populated hidden input with “”.
handleRichText() is called from updateRepeaterItemIndexes(), which runs on init
(harmless, everything is still empty) and on addRepeaterField() /
removeRepeaterField() — hence the exact trigger.
Note on Quill mode: there “.brf-rich-text-container” is a
undefined. handleRichText() currently matches neither of the two modes.
Suggested fix
Before reading the textarea in handleRichText(), sync the editor:
if (window.tinymce) {
const ed = window.tinymce.get(e.id);
if (ed) ed.save();
}
and skip / handle the Quill case separately (read .ql-editor innerHTML, or leave
the hidden input untouched, since Quill already keeps it in sync via text-change).
Current workaround
A small frontend script that hooks every TinyMCE instance inside .brf-field-rich-text
and calls editor.save() on input/change/keyup/blur/ExecCommand/SetContent, which keeps
the textarea current so Bricksforge’s own copy logic reads the right value.