Flutter_form_builder: How can I clear a form instead of resetting it?

Created on 11 Nov 2020  路  10Comments  路  Source: danvick/flutter_form_builder

I am trying to figure out a way to clear a form with a button. Not reset it to initial values like the reset method does on FormBuilderState but instead set every field to null or empty depending on their type.
I tried calling setAttributeValue but it doesn't affect my fields:

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

class TestView extends StatefulWidget {
  TestView({Key key}) : super(key: key);

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

class _TestViewState extends State<TestView> {
  final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();

  bool _filterOnSurface = false;

  @override
  void initState() {
    _filterOnSurface = false;
    super.initState();
  }

  void _saveFilter() {
    if (_fbKey.currentState.saveAndValidate()) {
      print(_fbKey.currentState.value);
      Navigator.pop(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Test'),
        actions: [
          IconButton(
            icon: Icon(Icons.save),
            onPressed: _saveFilter,
          ),
        ],
      ),
      body: FormBuilder(
        key: _fbKey,
        initialValue: {
          'filterOnSurface': _filterOnSurface,
          'myText': 'something',
        },
        child: SafeArea(
          child: ListView(
            children: [
              FormBuilderSwitch(
                attribute: 'filterOnSurface',
                label: Text('Filter on surface'),
                onChanged: (value) {
                  setState(() {
                    _filterOnSurface = value;
                  });
                },
              ),
              FormBuilderTextField(
                attribute: 'myText',
                decoration: InputDecoration(
                  labelText: 'My text',
                ),
              ),
            ],
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        tooltip: 'Clear',
        child: Icon(Icons.delete),
        onPressed: () {
          _fbKey.currentState.setAttributeValue('filterOnSurface', false);
          _fbKey.currentState.setAttributeValue('myText', '');
        },
      ),
    );
  }
}

Most helpful comment

FYI, I upgraded to version 4 now that it has been released, and patchValue does the trick.

All 10 comments

Have you tried FormBuilder.patchValue?

I don't see any such method in the documentation, neither in FormBuilder nor in FormBuilderState. Not even in the source code.

@sarbogast I was referring to the FormBuilderState.patchValue method. I thought that this was available in version 3 as well as version 4, but it appears to be version 4 only.

I am a little surprised that setAttributeValue is not working for you. I wonder if the problem is that you need to wrap the call in setState to trigger a re-build? Like:

        onPressed: () {
          setState(() {
            _fbKey.currentState.setAttributeValue('filterOnYear', false);
            _fbKey.currentState.setAttributeValue('myText', '');
          });
        },

Oh, never mind... It looks like a setState is embedded in the setAttributeValue call.

I can get this working fine with version 4 and using patchValue -- however, I noticed that the form has an attribute filterOnSurface , but the onPressed handler sets filterOnYear to false. _Is that perhaps the root issue?_

No that's just a detail related to the fact I tried to simplify a form that's much more complex in reality, with a lot more fields.

I corrected the code above. And when I click the floating action button, nothing happens, the fields in the form remain the same.

@sarbogast I can confirm your issue with version 3. As I mentioned, version 4 (still pre-release) has a more elegant solution.

However, to make version 3 work, try this:

        onPressed: () {
          final fields = _fbKey.currentState.fields;
          fields['filterOnSurface'].currentState.didChange(false);
          fields['myText'].currentState.didChange('');
        },

That worked. Thanks.

FYI, I upgraded to version 4 now that it has been released, and patchValue does the trick.

Was this page helpful?
0 / 5 - 0 ratings