Home > OS >  How to programatically assign value to Flutter AutoComplete from Button?
How to programatically assign value to Flutter AutoComplete from Button?

Time:12-19

I have a single page Flutter expense-tracking application with a Scaffold.

There is an AutoComplete field for expense category in the Scaffold Body that the user could directly use this field.

There is also a "Quick Select" MaterialButton in the Scaffold Drawer that I'd like to automatically set the value of the AutoComplete field to something like "Groceries".

Unfortunately, I cannot get the MaterialButton to update the AutoComplete.

How can I get the MaterialButton to update the AutoComplete value?

Here's my code:

// State Variable
late String category = "";

// Quick Select Button in Drawer
MaterialButton(
    child: const Text('Groceries'),
    onPressed: () {
        _categoryController.text = "Groceries";
        category = "Groceries";
        Navigator.pop(context);
    },
),

// Auto Complete Field on Page
Autocomplete<String>(

    optionsBuilder: (TextEditingValue textEditingValue) {
      return categoriesList
          .where((theString) => theString
              .toLowerCase()
              .startsWith(
                  textEditingValue.text.toLowerCase()))
          .toList();
    },
    
    fieldViewBuilder: (BuildContext context,
        TextEditingController fieldTextEditingController,
        FocusNode fieldFocusNode,
        VoidCallback onFieldSubmitted) {
      return TextFormField(
        controller: fieldTextEditingController,
        focusNode: fieldFocusNode,
        decoration:
            const InputDecoration(labelText: 'Category'),
        onChanged: (value) => {
          _categoryController.text = value.toString(),
        },
      );
    },
    
    displayStringForOption: (value) => value,
    
    onSelected: (value) {
      _categoryController.text = value.toString();
    },
),

This will work fine if I change the AutoComplete to a simple TextFormField.

Any comments and/or suggestions are welcome!

CodePudding user response:

Try something like this:

TextEditingController? _categoryController;

MaterialButton(
  child: const Text('Groceries'),
  onPressed: () {
    _categoryController?.text = "Groceries";
    // Navigator.pop(context);
  },
),
Autocomplete<String>(
  optionsBuilder: (TextEditingValue textEditingValue) {
    return categoriesList
        .where((theString) => theString
            .toLowerCase()
            .startsWith(textEditingValue.text.toLowerCase()))
        .toList();
  },
  fieldViewBuilder: (
    BuildContext context,
    TextEditingController fieldTextEditingController,
    FocusNode fieldFocusNode,
    VoidCallback onFieldSubmitted,
  ) {
    _categoryController ??= fieldTextEditingController; // initialize _categoryController if null
    return TextFormField(
      controller: _categoryController, // use _categoryController everywhere to update the TextFormField
      focusNode: fieldFocusNode,
      decoration: const InputDecoration(labelText: 'Category'),
    );
  },
  displayStringForOption: (value) => value,
)
  • Related