Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter 2 - Set initial value of an Autocomplete TextFormField

I can't use TextEditingController because the TextFormField uses the Autocomplete fieldViewBuilder TextEditingController

Autocomplete(
                optionsBuilder: (TextEditingValue textEditingValue) {
                  if (textEditingValue.text == '') return [];

                  return this
                      .productNames
                      .where((Map<String, dynamic> option) {
                    return option['ar']
                        .toLowerCase()
                        .contains(textEditingValue.text.toLowerCase());
                  });
                },
                fieldViewBuilder: (context, textEditingController,
                        focusNode, onFieldSubmitted) =>
                    TextFormField(                             
                  controller: textEditingController,//uses fieldViewBuilder TextEditingController
                   focusNode: focusNode,
                ),
              ),
like image 228
ibrahimxcool Avatar asked Mar 23 '21 10:03

ibrahimxcool


People also ask

How do you add initial value in TextFormField Flutter?

The TextField initial value in Flutter can be added in the following three ways: Using TextEditingController. Providing Direct TextEditingController. Using TextFormField.

How do you implement Autocomplete in Flutter?

In Flutter, that can be done by using Autocomplete widget. It's a widget that allows the user to type on a text input and choose from a list of options. In this tutorial, I am going to show you how to use the widget, including how to set the options, customize the TextField , and handle option selected event.


3 Answers

EDIT

I just realized you are using TextFormField which has a parameter called initialValue. IF you do not need the textediting controller, this answer should work

fieldViewBuilder: (context, textEditingController,
                        focusNode, onFieldSubmitted) =>
                    TextFormField(                             
             
                   focusNode: focusNode,
                   initialValue:"Your initial Value",
                ),

or if you are using your controller try

fieldViewBuilder: (context, textEditingController,
                        focusNode, onFieldSubmitted) =>
                    TextFormField(                             
                  controller: textEditingController..text="Initial Value",
                   focusNode: focusNode,
                ),

ORIGINAL ANSWER

Why don't you use that text editing controller itself. The code will be something like this

Autocomplete(
                optionsBuilder: (TextEditingValue textEditingValue) {
                  if (textEditingValue.text == '') return [];

                  return this
                      .productNames
                      .where((Map<String, dynamic> option) {
                    return option['ar']
                        .toLowerCase()
                        .contains(textEditingValue.text.toLowerCase());
                  });
                },
                fieldViewBuilder: (context, textEditingController,
                        focusNode, onFieldSubmitted){
                    textEditingController.text  = "Your initial text";// You can use the next snip of code if you dont want the initial text to come when you use setState((){});  
                    return TextFormField(                             
                  controller: textEditingController,//uses fieldViewBuilder TextEditingController
                   focusNode: focusNode,
                ),
               }
              ),

If you are using setState and the above piece of code keeps replacing the text with the initial text, do something like

Autocomplete(
                optionsBuilder: (TextEditingValue textEditingValue) {
                  if (textEditingValue.text == '') return [];

                  return this
                      .productNames
                      .where((Map<String, dynamic> option) {
                    return option['ar']
                        .toLowerCase()
                        .contains(textEditingValue.text.toLowerCase());
                  });
                },
                fieldViewBuilder: (context, textEditingController,
                        focusNode, onFieldSubmitted){
                    textEditingController.text = textEditingController.text  == ""? "Inital Text":textEditingController.text;// You can use the next snip of code if you dont want the initial text to come when you use setState((){});  
                    return TextFormField(                             
                  controller: textEditingController,//uses fieldViewBuilder TextEditingController
                   focusNode: focusNode,
                ),
               }
              ),

The last solution is not too elegant but works. I will let you know if I find a better solution. You can even assign this textEditingController to a global variable declared at the top and access it from anywhere in the code. And instead of checking if the text is empty, increase the value of a new variable everytime you setState and if the value is == 0, you can set initial text

like image 149
Siddharth Agrawal Avatar answered Oct 20 '22 23:10

Siddharth Agrawal


AutoComplete has a named parameter initialValue for this.

Autocomplete<AutocompletePrediction>(  
    initialValue: const TextEditingValue(text: "Initial value"),  
    fieldViewBuilder: ...
    ...  
)  
like image 25
log0 Avatar answered Oct 21 '22 00:10

log0


This is the solution I found for TextFormField. Making sure the controller is updated at the end of the frame.

fieldViewBuilder: (BuildContext context,
  TextEditingController fieldTextEditingController,
  FocusNode fieldFocusNode,
  VoidCallback onFieldSubmitted) {

  SchedulerBinding.instance?.addPostFrameCallback((_) { // <--- this part
    var initialValue = someValueThatGotUpdatedDuringBuild;

    fieldTextEditingController.text = initialValue;
  });
  return TextFormField(...);
}
...
like image 29
davidcv5 Avatar answered Oct 20 '22 23:10

davidcv5