Dynamic forms in Flutter refer to the ability to create forms that can change their structure and content based on certain conditions or user interactions. It allows you to build flexible and interactive user interfaces for collecting and validating user input. Dynamic forms are auto-generated forms that are fully controlled by the user’s actions and decisions, thus giving a real-time experience to the user.

Differences Between Static and Dynamic Forms

Static forms are forms having a fixed number of widgets or fields in which updates are only possible to get updated with the new update to the application. On the other hand, dynamic forms can be updated without the new update. The fields, options, and all the important information are passed with the json file which is fetched and fields are displayed as per the information from json.

Why dynamic forms in Flutter?

Suppose you are building an application that consists of a form that is several pages. Along with it the fields of the forms may change or update. In that case, dynamic forms come into use. You can just play around with the form fields in the application as per user experience. And also you can achieve it without sending updates to the app stores.

Alright Now let’s dive into the project.

Step 1: Get Value from JSON

Here, I have just designed the json, but in real cases, you can fetch it from the API endpoint by making HTTP requests.

Now we design the form.json file inside assets/json.

[
    {
        "title": "Title 1",
        "fields": [
            {
                "label": "Text",
                "fieldType": "TextInput"
            }
        ]
    },
    {
        "title": "Title 2",
        "fields": [
            {
                "label": "Date time",
                "fieldType": "DatetimePicker"
            },
            {
                "label": "T&C",
                "fieldType": "SwitchInput"
            },
            {
                "label": "Select",
                "fieldType": "SelectList",
                "options": [
                    {
                        "color": "#FFFFFF",
                        "is_faulty": false,
                        "optionLabel": "Option Label 1",
                        "optionValue": "Option 1"
                    },
                    {
                        "color": "#FFFFFF",
                        "is_faulty": false,
                        "optionLabel": "Option Label 2",
                        "optionValue": "Option 2"
                    },
                    {
                        "color": "#FFFFFF",
                        "is_faulty": false,
                        "optionLabel": "Option Label 3",
                        "optionValue": "Option 3"
                    }
                ]
            }
        ]
    }
]

Here you can see, we have lists of objects that hold the form field types and values.

After that you need to provide path to the json file inside pubsec.yaml file.
uses-material-design: true
assets:
    - assets/json/
//other code

Step 2: Create a model

Now we have the json file. To obtain the json in the form of an object you need to now create the model from the json.

class ResponseForm {
  String? title;
  List<Fields>? fields;

  ResponseForm({this.title, this.fields});

  ResponseForm.fromJson(Map<String, dynamic> json) {
    title = json['title'];
    if (json['fields'] != null) {
      fields = <Fields>[];
      json['fields'].forEach((v) {
        fields!.add(Fields.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['title'] = title;
    if (fields != null) {
      data['fields'] = fields!.map((v) => v.toJson()).toList();
    }

    return data;
  }
}

class Fields {
  String? label;
  String? fieldType;
  List<Options>? options;

  Fields({
    this.label,
    this.fieldType,
    this.options,
  });

  Fields.fromJson(Map<String, dynamic> json) {
   
    label = json['label'];
    if (json['options'] != null) {
      options = <Options>[];
      json['options'].forEach((v) {
        options!.add(Options.fromJson(v));
      });
    }
    
    fieldType = json['fieldType'];
  
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    
    data['label'] = label;
  
    if (options != null) {
      data['options'] = options!.map((v) => v.toJson()).toList();
    }
   
    
    data['fieldType'] = fieldType;

    return data;
  }
}

class Options {
  String? color;
  bool? isFaulty;
  String? optionLabel;
  String? optionValue;

  Options({this.color, this.isFaulty, this.optionLabel, this.optionValue});

  Options.fromJson(Map<String, dynamic> json) {
    color = json['color'];
    isFaulty = json['is_faulty'];
    optionLabel = json['optionLabel'];
    optionValue = json['optionValue'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['optionLabel'] = optionLabel;
    data['optionValue'] = optionValue;
    return data;
  }
}

Step 3: Get Json Response

Now we are going to get the Json Response.

getFromJson() async {
    String data = await DefaultAssetBundle.of(context)
        .loadString("assets/json/form.json");
    final jsonResult = jsonDecode(data);

    setState(() {
      jsonResult.forEach(
          (element) => formResponse.add(ResponseForm.fromJson(element)));

      isLoading = false;
    });


  }

Step 4: Display form fields

As per the fieldType now display the form fields

ListView.separated(
      itemCount: formResponse[index].fields!.length,
      shrinkWrap: true,
      itemBuilder: (context, innerIndex) {
        return formResponse[index].fields![innerIndex].fieldType ==
                "DatetimePicker"
            ? myDatePicker()
            : formResponse[index].fields![innerIndex].fieldType == "TextInput"
                ? TextField(
                    decoration: InputDecoration(
                      border: const OutlineInputBorder(),
                      hintText: formResponse[index].fields![innerIndex].label,
                    ),
                  )
                : formResponse[index].fields![innerIndex].fieldType ==
                        "SelectList"
                    ? dropDownWidget(
                        formResponse[index].fields![innerIndex].options)
                    : formResponse[index].fields![innerIndex].fieldType ==
                            "SwitchInput"
                        ? SwitchListTile(
                            value: switchValue,
                            title: Text(
                                formResponse[index].fields![innerIndex].label!),
                            onChanged: (value) {
                              setState(() {
                                switchValue = !switchValue;
                              });
                            })
                        : const Text("Other type");
      },
      separatorBuilder: (BuildContext context, int index) {
        return const SizedBox(height: 10);
      },
    )

Conclusion

Here you learned how to create dynamic forms in Flutter. Keep in mind that they are not a good choice for applications having fixed field types and the forms are almost fixed. With the help of dynamic forms in Flutter, you can get the required form fields which can be reused throughout the application.

Thanks for reading this article.

Also, follow to get updated on exciting articles and projects.

If I got something wrong? Let me know in the comments. I would love to improve.

Full Code:

https://github.com/nbnD/dynamic_form

Let’s get connected

We can be friends. Find on FacebookLinkedinGithubYouTube

BuyMeACoffee, and Instagram.

Contribute: BuyMeACoffee

ContactContact Us

  1. tlovertonet Avatar

    I like the helpful info you provide in your articles. I will bookmark your weblog and check again here regularly. I am quite sure I will learn a lot of new stuff right here! Best of luck for the next!

  2. neurontnpi Avatar

    I am not sure where you’re getting your information, but great topic.

    1. flutterjunction Avatar

      Thank you neuron. Keep loving us.

  3. mango Avatar

    Most loved blog by developers

Leave a Reply

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

dynamic forms in Flutter

Related Post