Submitted by: HHH Consulting
Component: Pro Forms (nestable) — Repeater + Radio / Checkbox Severity: High — a saved choice is shown as a different choice, so an edit form displays the wrong value
Type: Front-end JS / syncRepeaterFields
Environment
| Bricksforge | 4.0.0 |
| Bricks | 2.4 |
| WordPress | 7.1.1 |
| PHP | 8.2.33 |
| ACF PRO | 6.8.10 |
| Browser | Chromium (reproduced independently of layout CSS) |
| Theme | Bricks Child Theme 1.1 |
Observed on a live edit form whose Repeater dataSource is ACF. The same Radio group outside a populated Repeater is not affected, because this path only runs from populateRepeaterData.
Summary
When a Repeater is filled from ACF (dataSource: acf), syncRepeaterFields() writes each subfield onto the matching control.
For a radio or checkbox it does not look for the input whose value equals the saved value. It takes the first input in that control and sets checked = !!value.
Any non-empty saved value therefore ticks the first choice. Previous is shown as Current when Current is the first radio. Step or Adopted is shown as Biological when Biological is the first radio.
A select in the same row is handled differently (element.value = savedValue) and can show the right option when the saved value is a plain id.
Steps to reproduce
- In ACF, create a Repeater. Add a Radio subfield (choices
CurrentandPrevious, return format Value) or a Checkbox subfield with the same choices. - Save a post with one repeater row and the choice set to Previous.
- In Bricks, add a Pro Form.
- Add a Repeater field:
dataSource= ACFfieldName= the repeater field key or namepostId= the post from step 2
- Inside the Repeater, add a Radio wrapper whose Custom ID matches the subfield name. Add two radios, values
CurrentandPrevious, with Current first. - View the page on the front end for that post.
Expected: Previous is ticked.
Actual: Current is ticked. The repeater’s data-brf-repeater-data still contains Previous.
Control: a Radio group that is not inside an ACF-populated Repeater is unchanged. This only happens in syncRepeaterFields.
Evidence
Saved row vs what was ticked
Edit form, spouse repeater, post loaded from ACF. data-brf-repeater-data on the repeater:
{
"s-p_person": [9242],
"s-p_type": "Spouse",
"s-p_current": ["Previous"]
}
The person select (value 9242) showed the correct person. The Current / Previous radios showed Current checked.
The first radio in that group is Current. The saved value is Previous. The loader ticked the first radio because the value is non-empty.
The same pass leaves Biological ticked on a Step / Family group when Biological is the first radio and the saved value is any non-empty string or object.
Code
bricksforge/assets/js/bricksforge_elements.js (4.0.0), inside syncRepeaterFields:
let input = field.querySelector("input, textarea, select");
if (input.type === "checkbox" || input.type === "radio") {
input.checked = !!savedValue;
} else {
input.value = savedValue;
}
querySelector returns the first input. !!savedValue is true for "Previous", ["Previous"], and { "value": "biological", "label": "Biological" }. The input’s own value is never compared.
Call path: handleRepeaters → populateRepeaterData → syncRepeaterFields.
Cause
syncRepeaterFields treats every radio and checkbox as a single boolean. It does not:
- read
input.value - walk the rest of the radio group
- unwrap a one-item array (
["Previous"], which is what an ACF checkbox stores) - unwrap an ACF select returned as
{ value, label }
So the first choice in the group is ticked whenever the saved value is truthy.
Suggested fix
Match the saved value to each radio or checkbox in the group:
const inputs = field.querySelectorAll("input[type=radio], input[type=checkbox]");
if (inputs.length) {
let raw = savedValue;
if (raw && typeof raw === "object" && !Array.isArray(raw) && raw.value != null) {
raw = raw.value;
}
const wanted = (Array.isArray(raw) ? raw : [raw]).map(v => String(v).toLowerCase());
inputs.forEach(input => {
input.checked = wanted.includes(String(input.value).toLowerCase());
});
return;
}
Leave the existing element.value = savedValue path for text, textarea, and select.
What this is not
- Not the wrong value in ACF. The repeater data attribute contains the saved choice.
- Not fixed by changing the ACF return format of the choice field. A string
"Previous"is still truthy, so the first radio is still ticked. - Not caused by theme or form CSS. The wrong radio has the
checkedproperty set.
Happy to test a patch on a staging install.