in flutter, how do I save data from a list of autogenerated textfields

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)

Leave a Reply

Your email address will not be published. Required fields are marked *