Flutter Dynamic DropdownFormField value not getting updated with the index

879 views Asked by At

I am new to Flutter and trying to build an app using Dynamic FormField, the issue is the dropdownformfield value isn't getting updated with the index. However, with the textformfield it works but doesn't work with the Dropdownformfield

enter image description here

enter image description here

When you press on the + button a new row will come up but if you look at the dropdownformfield the value gets blank and doesn't get updated with the row. Here is the code.

class DynamicWidgets extends StatefulWidget {
  @override
  _DynamicWidgetState createState() => _DynamicWidgetState();

  }


class _DynamicWidgetState extends State<DynamicWidgets> {
  final _formKey = GlobalKey<FormState>();
  TextEditingController _nameController;
  static List<String> dropdowndata=[null];
  static List<String> descriotiondata=[null];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _nameController = TextEditingController();
    _nameController.text = "XR";
  }

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Form(
      key: _formKey,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              padding: const EdgeInsets.only(right: 32.0),
              child: TextFormField(
                controller: _nameController,
                decoration: InputDecoration(hintText: 'Modality Name'),
                validator: (v) {
                  if (v.trim().isEmpty) return 'Please enter something';
                  return null;
                },
              ),
            ),
            Text("Add More Study"),
            SizedBox(
              height: 5,
            ),
            ..._getFields(),
            SizedBox(
              height: 10,
            ),
            FlatButton(
              onPressed: () {
                if (_formKey.currentState.validate()) {
                  _formKey.currentState.save();
                  debugPrint("Widget1 Key data: ${dropdowndata.toString()}");
                  debugPrint("Widget2 Key data: ${descriotiondata.toString()}");
                }
              },
              child: Text(
                'Submit',
                style: TextStyle(color: Colors.white),
              ),
              color: Colors.green,
            ),
          ],
        ),
      ),
    );
    throw UnimplementedError();
  }

  List<Widget> _getFields() {
    List<Widget> friendsTextFields = [];
    for (int i = 0; i < dropdowndata.length; i++) {
      friendsTextFields.add(Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        child: Row(
          children: [
            Expanded(child: DynamicFields(i)),
            SizedBox(
              width: 16,
            ),
            // we need add button at last friends row
            _addRemoveButton(i == dropdowndata.length - 1, i),
          ],
        ),
      ));
    }
    return friendsTextFields;
  }

  Widget _addRemoveButton(bool add, int index) {
    return InkWell(
      onTap: () {
        if (add) {
          // add new text-fields at the top of all friends textfields
          dropdowndata.insert(0, null);
          descriotiondata.insert(0, null);
        } else {
          dropdowndata.removeAt(index);
          descriotiondata.removeAt(index);
        }
        setState(() {});
      },
      child: Container(
        width: 30,
        height: 30,
        decoration: BoxDecoration(
          color: (add) ? Colors.green : Colors.red,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Icon(
          (add) ? Icons.add : Icons.remove,
          color: Colors.white,
        ),
      ),
    );
  }
}


class DynamicFields extends StatefulWidget {
  final int index;
  DynamicFields(this.index);
  @override
  _DynamicFieldsState createState() => _DynamicFieldsState();
}

class _DynamicFieldsState extends State<DynamicFields>{
  TextEditingController _descriptionController;
    var _selectedValue;
    var _dropdownvalue;
  String _myActivity;
  String _myActivityResult;
  static var _studynames = ["CT-62", "CT-53","CT-54","CT-50"];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._descriptionController=TextEditingController();

  }
  @override
  void dispose() {
    _descriptionController.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      _descriptionController.text = _DynamicWidgetState.descriotiondata[widget.index] ?? '';
      _selectedValue=_DynamicWidgetState.dropdowndata[widget.index] ?? '';
    });
    // TODO: implement build
    return Row(
      children: [
        Flexible(
          flex: 1,
          child: Container(
            margin: EdgeInsets.all(5.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(5.0),
              border: Border.all(
                  color: Colors.blueGrey, style: BorderStyle.solid, width: 0.80),
            ),
            child: Padding(
              padding: EdgeInsets.all(2.0),
              child: Material(
                shape:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
                elevation: 0.0,
                child: ListTile(
                  title: DropdownButton(
                    items: _studynames.map((String dropdownitem) {
                      return DropdownMenuItem<String>(
                        value: dropdownitem,
                        child: Text(
                          dropdownitem,
                          style: TextStyle(color: Color(0xFF4BC1FF)),
                        ),
                      );
                    }).toList(),
                    underline: Container(
                      height: 0,
                    ),
                    value: _dropdownvalue,
                    onChanged: (valueSelected) {
                      setState(() {
                        debugPrint("$valueSelected value selected");
                        _dropdownvalue = valueSelected;
                        _DynamicWidgetState.dropdowndata[widget.index] = valueSelected;

                      });
                    },
                  ),
                ),
              ),
            ),
          )
          ),

        SizedBox(width: 10),
        Flexible(
          flex: 1,
          child:  TextFormField(
            controller: _descriptionController,
            onChanged: (v) => _DynamicWidgetState.descriotiondata[widget.index] = v,
            decoration: InputDecoration(
                hintText: 'Study Description'
            ),
            validator: (v){
              if(v.trim().isEmpty) return 'Please enter Study Description';
              return null;
            },
          ),
        )
      ],
    );
    throw UnimplementedError();
  }

}
1

There are 1 answers

1
HyopeR On

You are not using the list data you have created while getting the "dropdown" values in the field under "_DynamicFieldsState". Therefore, your application is not aware of the value it will receive in these areas. Review if I just changed some values in the "_DynamicFieldsState" field.

import 'package:flutter/material.dart';

class DynamicWidgets extends StatefulWidget {
  @override
  _DynamicWidgetState createState() => _DynamicWidgetState();

}


class _DynamicWidgetState extends State<DynamicWidgets> {
  final _formKey = GlobalKey<FormState>();
  TextEditingController _nameController;
  static List<String> dropdowndata=[null];
  static List<String> descriotiondata=[null];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _nameController = TextEditingController();
    _nameController.text = "XR";
  }

  @override
  void dispose() {
    _nameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      resizeToAvoidBottomPadding: false,

      body: Form(
        key: _formKey,
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(right: 32.0),
                child: TextFormField(
                  controller: _nameController,
                  decoration: InputDecoration(hintText: 'Modality Name'),
                  validator: (v) {
                    if (v.trim().isEmpty) return 'Please enter something';
                    return null;
                  },
                ),
              ),
              Text("Add More Study"),
              SizedBox(
                height: 5,
              ),
              ..._getFields(),
              SizedBox(
                height: 10,
              ),
              FlatButton(
                onPressed: () {
                  if (_formKey.currentState.validate()) {
                    _formKey.currentState.save();
                    debugPrint("Widget1 Key data: ${dropdowndata.toString()}");
                    debugPrint("Widget2 Key data: ${descriotiondata.toString()}");
                  }
                },
                child: Text(
                  'Submit',
                  style: TextStyle(color: Colors.white),
                ),
                color: Colors.green,
              ),
            ],
          ),
        ),
      ),
    );
    throw UnimplementedError();
  }

  List<Widget> _getFields() {
    List<Widget> friendsTextFields = [];
    for (int i = 0; i < dropdowndata.length; i++) {
      friendsTextFields.add(Padding(
        padding: const EdgeInsets.symmetric(vertical: 16.0),
        child: Row(
          children: [
            Expanded(child: DynamicFields(i)),
            SizedBox(
              width: 16,
            ),
            // we need add button at last friends row
            _addRemoveButton(true, i),
          ],
        ),
      ));
    }
    return friendsTextFields;
  }

  Widget _addRemoveButton(bool add, int index) {
    print('index:' + index.toString());
    return InkWell(
      onTap: () {
        if (add) {
          // add new text-fields at the top of all friends textfields
          dropdowndata.insert(0, null);
          descriotiondata.insert(0, null);
        } else {
          dropdowndata.removeAt(index);
          descriotiondata.removeAt(index);
        }
        setState(() {});
      },
      child: Container(
        width: 30,
        height: 30,
        decoration: BoxDecoration(
          color: (add) ? Colors.green : Colors.red,
          borderRadius: BorderRadius.circular(20),
        ),
        child: Icon(
          (add) ? Icons.add : Icons.remove,
          color: Colors.white,
        ),
      ),
    );
  }
}


class DynamicFields extends StatefulWidget {
  final int index;
  DynamicFields(this.index);
  @override
  _DynamicFieldsState createState() => _DynamicFieldsState();
}

class _DynamicFieldsState extends State<DynamicFields>{
  TextEditingController _descriptionController;
  var _selectedValue;
  var _dropdownvalue;
  String _myActivity;
  String _myActivityResult;
  static var _studynames = ["CT-62", "CT-53","CT-54","CT-50"];
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    this._descriptionController=TextEditingController();

  }
  @override
  void dispose() {
    _descriptionController.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      _descriptionController.text = _DynamicWidgetState.descriotiondata[widget.index] ?? '';
      _selectedValue=_DynamicWidgetState.dropdowndata[widget.index] ?? '';
    });
    // TODO: implement build
    return Row(
      children: [
        Flexible(
            flex: 1,
            child: Container(
              margin: EdgeInsets.all(5.0),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(5.0),
                border: Border.all(
                    color: Colors.blueGrey, style: BorderStyle.solid, width: 0.80),
              ),
              child: Padding(
                padding: EdgeInsets.all(2.0),
                child: Material(
                  shape:
                  RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
                  elevation: 0.0,
                  child: ListTile(
                    title: DropdownButton(
                      items: _studynames.map((String dropdownitem) {
                        return DropdownMenuItem<String>(
                          value: dropdownitem,
                          child: Text(
                            dropdownitem,
                            style: TextStyle(color: Color(0xFF4BC1FF)),
                          ),
                        );
                      }).toList(),
                      underline: Container(
                        height: 0,
                      ),
                      value: _DynamicWidgetState.dropdowndata[widget.index], // Here
                      onChanged: (valueSelected) {
                        setState(() {
                          debugPrint("$valueSelected value selected");
                          _dropdownvalue = _DynamicWidgetState.dropdowndata[widget.index]; // Here
                          _DynamicWidgetState.dropdowndata[widget.index] = valueSelected;

                        });
                      },
                    ),
                  ),
                ),
              ),
            )
        ),

        SizedBox(width: 10),
        Flexible(
          flex: 1,
          child:  TextFormField(
            controller: _descriptionController,
            onChanged: (v) => _DynamicWidgetState.descriotiondata[widget.index] = v,
            decoration: InputDecoration(
                hintText: 'Study Description'
            ),
            validator: (v){
              if(v.trim().isEmpty) return 'Please enter Study Description';
              return null;
            },
          ),
        )
      ],
    );
    throw UnimplementedError();
  }

}