Issue
In my app I have a list of bedrooms that a person can select, if a user selects 1 and 2 bedrooms, two textfields are generated from those selecttions
_apartmentBedrooms.length > 0
? Container(
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: _apartmentBedrooms.length,
itemBuilder: (context, index) {
_controllers.add(new TextEditingController());
print(_controllers[index]);
return BlocBuilder<AddPropertyBloc, AddPropertyState>(
builder: (context, state) {
return Padding(
padding: const EdgeInsets.only(left: 15, right: 15, top: 10),
child: Container(
padding: EdgeInsets.only(right: 15, left: 10),
height: 40,
decoration: BoxDecoration(
color: ColorConfig.smokeLight,
borderRadius: BorderRadius.circular(5),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: TextFormField(
controller: _controllers[index],
onFieldSubmitted: (value) {
// BlocProvider.of<AddPropertyBloc>(context).add(EnteredPriceEvent(price: value));
print(_controllers[index].text);
prices.add(_controllers[index].text);
print(prices);
},
keyboardType: TextInputType.number,
style: TextStyle(
fontFamily: FontConfig.regular,
fontSize: Sizeconfig.small,
color: ColorConfig.dark,
),
decoration: InputDecoration(
hintText: _apartmentBedrooms[index].toString() + " bedroom Price*",
hintStyle: TextStyle(
fontFamily: FontConfig.regular,
fontSize: Sizeconfig.small,
color: ColorConfig.dark,
),
border: InputBorder.none,
),
),
),
),
);
},
);
},
),
)
: Text("choose bedrooms first"),
I have a list of textEditingControllers that are generated for each bedroom selected. The problem is if I use onChanged it ends up adding to the list infinite items from any changed item, when I use onfieldsubitted and I change any value, they get added as new items on list which I dont want. I want save the prices for each bedroom whether changed or just added. How can I achieve that.
Solution
You can simply generate the Controller when there is no controller for the index by using a Map. Something like this:
Map<int, TextEditingController> _mapControllers = Map();
TextEditingController _controllerOf(int index) {
var item = _mapControllers[index];
if(item == null) {
item = TextEditingController();
_mapControllers[index] = item;
}
return item;
}
where you can use it like this:
TextFormField(
controller: _controllerOf(index),
...
)
Then, you can get the text from controllers by something like this:
List<String> _textsOf(Map<int, TextEditingController> mapControllers) {
// Sort map by index of the builder.
var sortedKeys = mapControllers.keys.toList()..sort();
List<String> texts = [];
for(var key in sortedKeys) {
texts.add(mapControllers[key].text);
}
return texts;
}
Please be noted, I haven’t test the code yet.
Answered By – ישו אוהב אותך
Answer Checked By – Clifford M. (FlutterFixes Volunteer)