Checkbox form validation

A cleaner solution to this problem is to make a class that extends FormField<bool>

Here is how I accomplished this:

class CheckboxFormField extends FormField<bool> {
  CheckboxFormField(
      {Widget title,
      FormFieldSetter<bool> onSaved,
      FormFieldValidator<bool> validator,
      bool initialValue = false,
      bool autovalidate = false})
      : super(
            onSaved: onSaved,
            validator: validator,
            initialValue: initialValue,
            builder: (FormFieldState<bool> state) {
              return CheckboxListTile(
                dense: state.hasError,
                title: title,
                value: state.value,
                onChanged: state.didChange,
                subtitle: state.hasError
                    ? Builder(
                        builder: (BuildContext context) =>  Text(
                          state.errorText,
                          style: TextStyle(color: Theme.of(context).errorColor),
                        ),
                      )
                    : null,
                controlAffinity: ListTileControlAffinity.leading,
              );
            });
}

in case if you want to put your checkbox directly in your Form widget tree you can use solution provided below with FormField widget. Instead of using ListTile I used rows and columns as my form was requiring different layout.

FormField<bool>(
  builder: (state) {
    return Column(
      children: <Widget>[
        Row(
          children: <Widget>[
            Checkbox(
              value: checkboxValue,
              onChanged: (value) {
                setState(() {
//save checkbox value to variable that store terms and notify form that state changed
                  checkboxValue = value;
                  state.didChange(value);
                });
              }),
            Text('I accept terms'),
          ],
        ),
//display error in matching theme
        Text(
          state.errorText ?? '',
          style: TextStyle(
            color: Theme.of(context).errorColor,
          ),
        )
      ],
    );
  },
//output from validation will be displayed in state.errorText (above)
  validator: (value) {
    if (!checkboxValue) {
      return 'You need to accept terms';
    } else {
      return null;
    }
  },
),

Tags:

Flutter