Nested Subform field with `min` attribute or with default value saves with error
Steps to reproduce the issue
https://www.awesomescreenshot.com/video/28634289?key=0cd544c850693dfbd16aaaccae2adae0
Subform into a subform doesnt save correctly the data. Also showon doesnt work right.
I attached a module that i used in the video and you can recreate the problem by going into the special hours tab and trying to add something there and save it. In the first basic tab everything works fine as expected.
When a subform into a subform save doesnt work as expected.
Expected result
Show on to work and save the data as we did them.
Actual result
The data and structure changes and adds more than it should
System information (as much as possible)
Joomla 5.1.0
Additional comments
It is because min attribute in the nested subfrom seems buggy. Without min="1" it works fine.
About radio switch, there already an issue #40160
Thanks a lot! I ll remove it then <3 Removing min attribute also fixed the show on functionallity.
If i find something it could help more i ll attach it here!
Note: this also happen when nested subform have default value.
When using a
name="jform[sections][sectionsX][subsections][subsections0][id]"
These placeholders are never replaced with actual indexes, so the form breaks on submit or validation. This only happens on initial load — dynamically added rows via the "+" button work correctly because the correct parent index is known by then.
To support min="1" in nested subforms without breaking field names, you can add the following code after this.fixUniqueAttributes(row, count); inside the addRow() method:
// Replace placeholder index 'X' in name attributes for nested subforms.
const nameAttr = this.name || '';
const match = nameAttr.match(/[?(\w+)]?$/);
if (match) {
const groupName = match[1];
const pattern = new RegExp((\\[${groupName})X(\\]), 'g');
row.querySelectorAll('[name]').forEach(el => {
el.name = el.name.replace(pattern, $1${count}$2);
});
}
This replaces placeholders like [sectionX] with [section0], [section1], etc., based on the current subform index. The replacement is scoped to the correct group name by dynamically extracting it from this.name — although I’m still wondering whether this name is always accurate, since the generated field names often use a plural form (e.g. sections) instead of the singular field name (section).