Flutter - FormBuilder enable field based on checkbox value

138 views Asked by At

I need to enable a FormBuilderTextField based on the value the user selects in a FormBuilderCheckboxGroup. This is an example:

import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';

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

  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  final _formKey = GlobalKey<FormBuilderState>();

  bool isEnabled = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('My Form'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: FormBuilder(
          key: _formKey,
          child: Column(
            children: [
              FormBuilderCheckboxGroup(
                name: 'checkboxGroup1',
                options: const [
                  FormBuilderFieldOption(
                      value: 'option1', child: Text('Option 1')),
                  FormBuilderFieldOption(
                      value: 'option2', child: Text('Option 2')),
                  FormBuilderFieldOption(
                      value: 'option3', child: Text('Option 3')),
                ],
                onChanged: (value) {
                  setState(() {
                    isEnabled = _formKey
                        .currentState!.fields['checkboxGroup1']!.value!
                        .contains('option3');
                  });
                },
              ),
              const SizedBox(height: 16),
              FormBuilderTextField(
                enabled: isEnabled,
                name: 'textField1',
                decoration: const InputDecoration(labelText: 'Text Field 1'),
              ),
              const SizedBox(height: 16),
              FormBuilderCheckboxGroup(
                name: 'checkboxGroup2',
                options: const [
                  FormBuilderFieldOption(
                      value: 'option4', child: Text('Option 4')),
                  FormBuilderFieldOption(
                      value: 'option5', child: Text('Option 5')),
                  FormBuilderFieldOption(
                      value: 'option6', child: Text('Option 6')),
                ],
                onChanged: (value) {
                  setState(() {
                    isEnabled = _formKey
                        .currentState!.fields['checkboxGroup2']!.value!
                        .contains('option6');
                  });
                },
              ),
              const SizedBox(height: 16),
              FormBuilderTextField(
                enabled: isEnabled,
                name: 'textField2',
                decoration: const InputDecoration(labelText: 'Text Field 2'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

enter image description here

I need to enable only the related text field based on the checkbox selection, however, it is enabling both text fields at the same time

Has anyone had a similar experience and could give me some hints?

Thank you

[EDIT]: I want to keep the same variable "isEnabled" for both fields

1

There are 1 answers

1
Lucas Tomic On

The problem is that you are using the same variable isEnabled in both fields. You should use a variable for each one

class _MyFormState extends State<MyForm> {
  final _formKey = GlobalKey<FormBuilderState>();

  bool enableFirstOne = false;
  bool enableSecondOne = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('My Form'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: FormBuilder(
          key: _formKey,
          child: Column(
            children: [
              FormBuilderCheckboxGroup(
                name: 'checkboxGroup1',
                options: const [
                  FormBuilderFieldOption(
                      value: 'option1', child: Text('Option 1')),
                  FormBuilderFieldOption(
                      value: 'option2', child: Text('Option 2')),
                  FormBuilderFieldOption(
                      value: 'option3', child: Text('Option 3')),
                ],
                onChanged: (value) {
                  setState(() {
                    enableFirstOne = _formKey
                        .currentState!.fields['checkboxGroup1']!.value!
                        .contains('option3');
                  });
                },
              ),
              const SizedBox(height: 16),
              FormBuilderTextField(
                enabled: enableFirstOne,
                name: 'textField1',
                decoration: const InputDecoration(labelText: 'Text Field 1'),
              ),
              const SizedBox(height: 16),
              FormBuilderCheckboxGroup(
                name: 'checkboxGroup2',
                options: const [
                  FormBuilderFieldOption(
                      value: 'option4', child: Text('Option 4')),
                  FormBuilderFieldOption(
                      value: 'option5', child: Text('Option 5')),
                  FormBuilderFieldOption(
                      value: 'option6', child: Text('Option 6')),
                ],
                onChanged: (value) {
                  setState(() {
                    enableSecondOne = _formKey
                        .currentState!.fields['checkboxGroup2']!.value!
                        .contains('option6');
                  });
                },
              ),
              const SizedBox(height: 16),
              FormBuilderTextField(
                enabled: enableSecondOne,
                name: 'textField2',
                decoration: const InputDecoration(labelText: 'Text Field 2'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}