ViKARLL
ViKARLL

Reputation: 111

Customizing the AutoComplete widget in Flutter

I am new to Flutter.

I need to have several Autocomplete fields in a single page, to receive user inputs (either afresh or a selection from the dropdown list attached to each Autocomplete field).

Such inputs from all the Autocomplete fields needs to be passed to variables and will be committed to the database (ObjectBox) finally, when the user taps a button at the bottom of the page.

My requirement is this; instead of writing some 25 lines per each Autocomplete field, I need to have a simple statement such as;

return Column(
    children: [
         MyAutocomplete (someList, someLabel, someHint);  

         SizedBox(width: 10.00,),

         MyAutocomplete (anotherList, anotherLabel, anotherHint);

         SizedBox(width: 10.00,),

        //several more MyAutocomplete fields

        // the ElevatedButton comes here


])

And, collect the user input to a dedicated variable for each field.

My question is; how can I build the above customozed MyAutocomplete widget in one place and how to call and pass parameters to it in the UI code as illustrated above?

Your help in this regard is much appreciated, please.

Sample code with the verbose version of the default Autocomplete widget is appended below (only two fields !).

Thanking you in advance,

Widget twoAutoCompleteBoxes() {

    const List<String> _kOptions = <String>['aardvark', 'bobcat', 'chameleon'];

 return Column(
     children: [
       Autocomplete<String>(
           optionsBuilder: (TextEditingValue textEditingValue) {
             if (textEditingValue.text == '') {
               return const Iterable<String>.empty();
             }
             return _kOptions.where((String option) {
               return option.contains(textEditingValue.text.toLowerCase());
             });
           },
           fieldViewBuilder: (BuildContext context,
               TextEditingController textEditingController,
               FocusNode focusNode, VoidCallback onFieldSubmitted) {
             return TextFormField(
               controller: textEditingController,
               decoration: myTextFieldDecoration(topLabel: "First Input", hintText: "Type or 
                      select from list"),
               focusNode: focusNode,
               onFieldSubmitted: (String value) {
                 onFieldSubmitted();
                  print('You just typed a new entry  $value');
               },
             );
           },
        onSelected: (String selection) {
          print('You just selected $selection');
        },
      ),

    SizedBox(
      width: 10.00,
    ),

      Autocomplete<String>(
        optionsBuilder: (TextEditingValue textEditingValue) {
          if (textEditingValue.text == '') {
            return const Iterable<String>.empty();
          }
          return _kOptions.where((String option) {
            return option.contains(textEditingValue.text.toLowerCase());
          });
        },
        fieldViewBuilder: (BuildContext context,
            TextEditingController textEditingController,
            FocusNode focusNode, VoidCallback onFieldSubmitted) {
          return TextFormField(
            controller: textEditingController,
            decoration: myTextFieldDecoration(topLabel: "Another Input", hintText: "Type or select from list"),
            focusNode: focusNode,
            onFieldSubmitted: (String value) {
              onFieldSubmitted();
              print('You just typed a new entry  $value');
            },
          );
        },
        onSelected: (String selection) {
          print('You just selected $selection');
        },
      ),
   ],
 );
} // END OF "Widget twoAutoCompleteBoxes()"

Also, my custom Decoration (just for completion's sake; you can ignore this code) :-

   // a common decoration for all types of text input fields, passed as the decoration 
     parameter
   InputDecoration myTextFieldDecoration(
      {String topLabel = "",
       String hintText = "",
       double cornerRadius = 5.0,
        Icon? icon}) {
     return InputDecoration(
       labelText: topLabel,
       hintText: hintText,
       icon: icon,
       border: OutlineInputBorder(
       borderRadius: BorderRadius.all(Radius.circular(cornerRadius)),
    ),
  );
}

Upvotes: 5

Views: 12116

Answers (2)

Parth Gupta
Parth Gupta

Reputation: 151

We can do this customization for the TextFormField.

        Autocomplete<String>(
            fieldViewBuilder:
                ((context, textEditingController, focusNode, onFieldSubmitted) =>
                    TextFormField(
                      controller: textEditingController,
                      focusNode: focusNode,
                      onFieldSubmitted: (value) => onFieldSubmitted,
                      decoration: InputDecoration(
                        contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 10),
                        border: OutlineInputBorder(gapPadding: 1),
                        hintText: "Search..",
                      ),
                    )),
         optionsBuilder: (TextEditingValue textEditingValue) {
              if (textEditingValue.text == '') {
                return const Iterable<String>.empty();
              } }
         //Add other Parameters you want.
        ),

Happy Coding :)

Upvotes: 0

log0
log0

Reputation: 10917

Declare a statefulWidget called MyAutocomplete and return the Autocomplete you want.

class MyAutocomplete extends StatefulWidget {
  final List<String> someList;

  const MyAutocomplete({
    Key? key,
    required this.someList,
  }) : super(key: key);

  @override
  State<MyAutocomplete> createState() =>
      _MyAutocompleteState();
}

class _MyAutocompleteState
    extends State<MyAutocomplete> {

  @override
  Widget build(BuildContext context) {
    return Autocomplete<AutocompletePrediction>(
      ... widget.someList ...
    );
  }
}

Upvotes: 0

Related Questions