Create dynamic TextFormField and its controller in Flutter

Adding a dynamic TextFormField may be a challenge in Native technologies but it is a very easy task in flutter. You can create dynamic TextFormField with its controllers. So lets start.
1. First create a StatefulWidget. In android studio, you can create a StatefulWidget class just by typing “stf” and press enter. Now StatefulWidget class will be created.

2. Create following two variables with a type of List.

  List<Widget> textFormFieldList = [];
  List<TextEditingController> controllerList = [];

One is for TextFormField and other for its controllers.

3. Now create widget function for TextFormField.

 Widget textField({index = 0}){
    return Center(
      child: SizedBox(
        width: 100,
        child: TextFormField(
          controller: controllerList[index],
          decoration: InputDecoration(
              isDense: true,
              contentPadding: EdgeInsets.all(10),
              focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: const BorderSide(color: Colors.red)),
              enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: const BorderSide(color: Colors.red))),
        ),
      ),
    );
  }

4. Create buttons to add TextFormField and print their values.

Widget addButton(){
    return ElevatedButton(onPressed: (){
      controllerList.add(TextEditingController());
      textFormFieldList.add(textField());
      setState(() {});
    }, child: const Text("ADD"));
  }

  Widget submitButton(){
    return ElevatedButton(onPressed: (){
      for (var element in controllerList) {
        print(element.text);
      }
    }, child: const Text("Submit"));
  }

5. Now finally, we will bind up all widgets in build function.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Dynamic TextFormField"),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const SizedBox(height: 20,),
           textFormFieldList.isNotEmpty ? ListView.builder(
              shrinkWrap: true,
              itemCount: textFormFieldList.length,
                itemBuilder: (context,index)=> Column(
                  children: [
                    textField(index: index),
                    const SizedBox(height: 10,),
                  ],
                )) : Container(),
            addButton(),
            submitButton()
          ],
        ),
      ),
    );
  }

Complete Code

import 'package:flutter/material.dart';

class DynamicTextField extends StatefulWidget {
  const DynamicTextField({super.key});

  @override
  State<DynamicTextField> createState() => _DynamicTextFieldState();
}

class _DynamicTextFieldState extends State<DynamicTextField> {
  List<Widget> textFormFieldList = [];
  List<TextEditingController> controllerList = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Dynamic TextFormField"),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            const SizedBox(height: 20,),
           textFormFieldList.isNotEmpty ? ListView.builder(
              shrinkWrap: true,
              itemCount: textFormFieldList.length,
                itemBuilder: (context,index)=> Column(
                  children: [
                    textField(index: index),
                    const SizedBox(height: 10,),
                  ],
                )) : Container(),
            addButton(),
            submitButton()
          ],
        ),
      ),
    );
  }

  Widget textField({index = 0}){
    return Center(
      child: SizedBox(
        width: 100,
        child: TextFormField(
          controller: controllerList[index],
          decoration: InputDecoration(
              isDense: true,
              contentPadding: EdgeInsets.all(10),
              focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: const BorderSide(color: Colors.red)),
              enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(10),
                  borderSide: const BorderSide(color: Colors.red))),
        ),
      ),
    );
  }

  Widget addButton(){
    return ElevatedButton(onPressed: (){
      controllerList.add(TextEditingController());
      textFormFieldList.add(textField());
      setState(() {});
    }, child: const Text("ADD"));
  }

  Widget submitButton(){
    return ElevatedButton(onPressed: (){
      for (var element in controllerList) {
        print(element.text);
      }
    }, child: const Text("Submit"));
  }
}

Output:

Leave a Reply