Repeating Sections
RepeatingSection creates dynamic arrays of field groups. Users can add and remove instances of the template fields, with configurable min/max constraints.
Basic Usage
dart
RepeatingSection(
title: 'Course Modules',
name: 'modules',
template: [
TextField(
name: 'module_title',
title: 'Module Title',
validations: [RequiredValidation(errorMessage: 'Title is required')],
),
NumberField(
name: 'duration_hours',
title: 'Duration (hours)',
allowDecimal: true,
validations: [
RequiredValidation(errorMessage: 'Duration is required'),
NumberRangeValidation(min: 0.5, max: 40, errorMessage: 'Between 0.5 and 40 hours'),
],
),
],
minInstances: 1,
maxInstances: 20,
displayMode: RepeatDisplayMode.expanded,
)Properties
| Property | Type | Default | Description |
|---|---|---|---|
title | String | required | Section heading |
name | String | required | Namespace for field names |
description | String? | null | Optional description |
template | List<ContentItem> | [] | Template fields for each instance |
minInstances | int | 1 | Minimum number of instances |
maxInstances | int? | null | Maximum instances (null = unlimited) |
displayMode | RepeatDisplayMode | expanded | Display style |
collapsible | bool | true | Whether instances can collapse |
hSpacing | double? | null | Horizontal spacing override |
vSpacing | double? | null | Vertical spacing override |
Display Modes
Expanded
All instances are always visible:
dart
RepeatingSection(
displayMode: RepeatDisplayMode.expanded,
// ...
)Accordion
Each instance is collapsible. Only one is expanded at a time by default:
dart
RepeatingSection(
displayMode: RepeatDisplayMode.accordion,
collapsible: true,
// ...
)Data Structure
Fields are namespaced with the section name and instance index:
modules.0.module_title = "Introduction"
modules.0.duration_hours = 2
modules.1.module_title = "Advanced Topics"
modules.1.duration_hours = 4The output in form.currentValues is an array:
json
{
"modules": [
{ "module_title": "Introduction", "duration_hours": 2 },
{ "module_title": "Advanced Topics", "duration_hours": 4 }
]
}LMS Example: Course Curriculum
A course creation form with repeating modules, each containing repeating lessons:
dart
final form = Form(
title: 'Course Curriculum',
items: [
TextField(
name: 'course_title',
title: 'Course Title',
validations: [RequiredValidation(errorMessage: 'Required')],
),
TextField(
name: 'course_description',
title: 'Description',
validations: [],
),
RepeatingSection(
title: 'Modules',
name: 'modules',
minInstances: 1,
maxInstances: 12,
displayMode: RepeatDisplayMode.accordion,
template: [
TextField(
name: 'title',
title: 'Module Title',
validations: [RequiredValidation(errorMessage: 'Required')],
),
NumberField(
name: 'order',
title: 'Order',
allowDecimal: false,
validations: [RequiredValidation(errorMessage: 'Required')],
),
TextField(
name: 'description',
title: 'Module Description',
validations: [],
),
NumberField(
name: 'duration',
title: 'Duration (hours)',
allowDecimal: true,
validations: [
NumberRangeValidation(
min: 0.5,
max: 40,
errorMessage: 'Must be 0.5-40 hours',
),
],
),
BooleanField(
name: 'is_mandatory',
title: 'Mandatory Module',
validations: [],
),
],
),
],
);Instance Management
The canAddInstance property checks whether more instances can be added:
dart
final section = form.items.whereType<RepeatingSection>().first;
if (section.canAddInstance) {
// Show "Add Module" button
}The namespaced field name helper:
dart
final fieldName = section.namespacedFieldName(2, 'title');
// => 'modules.2.title'FormArray Integration
Internally, RepeatingSection uses a FormArray in the parent FormGroup. Each instance is a nested FormGroup within the array:
dart
// Access the FormArray
final formArray = form.formGroup.control('modules') as FormArray;
// Number of instances
final count = formArray.controls.length;
// Access a specific instance's value
final firstModule = formArray.controls[0] as FormGroup;
final title = firstModule.control('title').value;Next Steps
- Formula Fields -- Computed field expressions
- Best Practices -- Form design guidelines
- Building Forms -- Step-by-step construction