Questions
1. How can we create dynamic forms in Flutter?
2. How can we access data from dynamic Forms?
Watch Video Tutorials
So let’s create a simple dynamic layout
We are gonna create a dynamic layout with one TexField when we tap on a plus button in the AppBar.
So this is how our AppBar is going to look like
AppBar(
title: Text('Dynamic Form'),
actions: [
IconButton(
icon: Icon(Icons.add),
onPressed: () async {
setState(() {
_count++;
});
},
),
IconButton(
icon: Icon(Icons.refresh),
onPressed: () async {
setState(() {
_count = 0;
_result = '';
});
},
)
],
)

For simplicity we will be incrementing a local counter and adding those many dynamic TextFields. In your real scenario, this data may be coming from your server or some where.
So declare a variable _count and initialize it to zero.
The other button in the AppBar will reset it to zero.
Let’s create a dynamic List based on the counter with each form having a TextField.
_row(int index) {
return Row(
children: [
Text('ID: $index'),
SizedBox(width: 30),
Expanded(
child: TextFormField(),
),
],
);
}
Now Let’s add it to a ListView.
Flexible(
child: ListView.builder(
shrinkWrap: true,
itemCount: _count,
itemBuilder: (context, index) {
return _row(index);
},
),
)
When the user taps the Counter button, it will add those many rows to the ListView.

Well, That’s all good!!.
But how do I get the values from the dynamic TextFields?
I can create a controller for each one and store it in a List of TextEditingControllers.
BUT!!!,
What if I have more than one TextFields and other input fields????
No Way is that I going to create more controllers, that would be a bad idea.
So Let’s see how we can solve it.
The easies way is to create a List of Map, like this.
List<Map<String, dynamic>> _values;
Yeah, so let’s see how to make this work.
TextFormField(
onChanged: (val) {
_onUpdate(index, val);
},
),
Here I assume the index is the key, you may have more complex objects in which you can use any of the member with unique value as a key.
The idea is to save the values in a json Object for each dynamic row.
Let’s see how we can achieve this.
You can see the ‘_onUpdate’ in the onChanged Event of the TextFormField. On this change, we are saving the value in a json object and adding to the _values array.
Let’s see how the method looks like.
_onUpdate(int index, String val) async {
int foundKey = -1;
for (var map in _values) {
if (map.containsKey("id")) {
if (map["id"] == index) {
foundKey = index;
break;
}
}
}
if (-1 != foundKey) {
_values.removeWhere((map) {
return map["id"] == foundKey;
});
}
Map<String, dynamic> json = {
"id": index,
"value": val,
};
_values.add(json);
}
In the above method, we are saving the values in a json object and adding the json object to the _values array. Before adding we are checking, if the key is already present, then remove that json object and add again.
You can copy and modify the json object as well.
The objects the map can be complex as you want, like this…
Map<String, dynamic> json = {
"id": index,
"value": { "text": val }, // set what ever you want here...
};
In this case I am using the ListView index as the key, but in a complex real world environment, you will have more solid meaningful keys.
In this way we save all the dynamic values from the dynamic form in a dynamic json list and the result will look like this.
Here I am displaying the saved values below the text fields for demonstration purposes. When the user edits the fields, it will be automatically updated.

Since we are removing and adding, the new object will be added at the end.
So, like I previously said, you can search and update the current object in the json map array.
It’s easy as it is.