Flutter 2 - Set initial value of an Autocomplete TextFormField
Solution 1
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
Solution 2
AutoComplete has a named parameter initialValue
for this.
Autocomplete<AutocompletePrediction>(
initialValue: const TextEditingValue(text: "Initial value"),
fieldViewBuilder: ...
...
)
Solution 3
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(...);
}
...
ibrahimxcool
🧠 - Don't practice what you don't want to become. 🥶 - Learning Angular & Flutter
Updated on November 26, 2022Comments
-
ibrahimxcool over 1 year
I can't use
TextEditingController
because theTextFormField
uses theAutocomplete
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, ), ),
-
ibrahimxcool about 3 yearsThis is what I'm currently using.. But every time I change the initial value and call
setState()
. I get the following error.. It does work but because of this error i assume its not the right way. The following assertion was thrown while dispatching notifications for TextEditingController: setState() or markNeedsBuild() called during build. -
Siddharth Agrawal about 3 yearsI am not exactly sure why this error is being thrown specific to your project, I will have to view the code files but the reason this is called is because you are calling the setState() method too early without the build being completed. The error does not matter as the build is completed instantly so the change can be run
-
ibrahimxcool about 3 yearsI have commented out the
textEditingController.text = "Your initial text";
from theAutocomplete()
. And when I callsetState()
it doesn't throw any error -
Siddharth Agrawal about 3 yearsI guess changing the text will rebuild the text field which will make an infinite loop. Try setting a counter variable in the top and set it to 0. Then in the builder, check if the counter variable is 0. If it is 0, set the initial text(It might rebuild it but only once) and add one to the counter variable. Maybe assign the initial text in a delayed async function
-
Siddharth Agrawal about 3 years@ibrahimxcool I have just added 2 new ways. Try the first one if you do not need the controller and try the second one if u need the controller
-
ibrahimxcool about 3 yearsThe autocomplete will not work if its
TextFormField
isn't using itsfieldViewBuilder
controller -
Siddharth Agrawal about 3 yearsThe second option uses the controller provided by the fieldViewBuilder and edits its text. You can use the counter variable solution I suggested before to solve the problem if the initial text keeps rebuilding.
-
davidcv5 about 3 years@thenoobslayer, see above, might solve your issue, if you're still having it.
-
user3056783 almost 3 yearsThis worked for me but in newer version of Flutter it should be ` WidgetsBinding.instance.addPostFrameCallback((_) { `