How to set TextFormField dynamically? - flutter

I am using flutter and I want to set text (String value) in TextFormField dynamically, means set value over press of a button.

use TextEditingController. Then assign it to the TextFormField then make use of the controller to assign the new data from wherever you want. If you want initial data assign it some value in the initState() function also use it on a stateful widget.
_textEditingController.text = "1";

You can make use of a StatefulWidget to adjust the initialValue property of your TextFormField.
class TextFieldChanger extends StatefulWidget {
#override
_TextFieldChangerState createState() => _TextFieldChangerState();
}
class _TextFieldChangerState extends State<TextFieldChanger> {
String presetText;
void _onPressed() {
setState(() {
presetText = 'updated text';
});
}
#override
Widget build(BuildContext context) => Column(children: [
TextFormField(initialValue: presetText),
RawMaterialButton(onPressed: _onPressed),
]);
}
In setState, I am assigning a new value to presetText and build will be called (with the updated initialValue) because of setState.

Related

How to update textiew text based on another variable in dart

I have the following code, shown below where every time I make changes to a text field, a function gets called, in my case doSomething(). However, I assumed that since I bound the value of the text to a variable, if that variable were to get updated, the textfield text would also update. This is not happening, and my question is, what would be the simplest way to make the textfield update its text every time the corresponding variable changes.
Edit: Just to clarify, I have no problem getting the doSomething() function to update other parts of the code, I am looking for the inverse where an external variable changes the text of the textfield
import 'package:flutter/material.dart';
class DynamicTextField extends StatefulWidget {
const DynamicTextField(
{
required this.value,
Key? key})
: super(key: key);
final double value;
#override
State<DynamicTextField> createState() =>
_DynamicTextFieldState(value);
}
class _DynamicTextFieldState extends State<DynamicTextField> {
_DynamicTextFieldState(this.value);
final double value;
late TextEditingController textChanged;
#override
void initState() {
textChanged = TextEditingController(text: value.toString());
super.initState();
}
#override
Widget build(BuildContext context) {
return TextField(
controller: textChanged,
onChanged: (text) {
doSomething();
},
);
}
}
you can change the TextField value with the textChanged controller you set to that widget.
String stringVariable = "some value";
textChanged.text = stringVariable;
you can then update the state with a normal SetState(() {}), and it should update the value in TextField
Your value is declared as final. Meaning it can only be set once. Try removing the final declaration.
I also see you’re also declaring the value variable twice, instead of referencing the original value variable.
The second declaration should be in the widgets build method & should = widget.value.
this will update the text everytime DynamicTextField get rebuild.
#override
void initState() {
textChanged = TextEditingController(text: widget.value.toString());
super.initState();
}
Depends how you use the DynamicTextField in another class. The life-cycle of StatefullWidget is call the initState once the widget initialize.

Clear TextField without controller in Flutter

My screen has multiple textfields, about 15 or so. I don't want to use TextEditingController due to performance reasons as the number of TextFields are likely to grow and I need to pass data from one widget to another back and forth. So I am using OnChanged method of the TextField and am setting a variable which will be used from the parent widget through a function. Now when I click on reset on the parent widget, how do I clear all the values in the TextField controls without using TextEditingController?
class Parent extends StatelessWidget {
String txt='';
myfunction(text)
{
txt=text;
}
#override
Widget build(BuildContext context) {
...
Foo(myfunction);
....
}
}
class Foo extends StatelessWidget {
final Function myfunction;
const Foo(this.myfunction);
#override
Widget build(BuildContext context) {
return TextField(
onChanged: (text) {
myfunction( text);
},...
}
}
You should try to declare all textfields with:
final TextEditingController name = TextEditingController();
final TextEditingController age = TextEditingController();
Create one method like this :
resetAll() {
name.clear();
name.clear();
}
then you call resetAll on reset button like below:
onPressed:() => resetAll()
It's not possible, but the text Fields will be reset if you dispose and reopen the screen holding the text Fields.

Flutter: How to insert text properly in a TextField/TextFormField

Let's say there is an empty TextFormField. After entering 2 characters manually I would like to insert a new one programmatically. So if length equals with 2 than insert a new one. It sounds really simple but strange behaviors appeared while I tried to achieve this. For example: The cursor continuously jumps back to the start and may cause this debug log:
Text selection index was clamped (-1->0) to remain in bounds. This may not be your fault, as some keyboards may select outside of bounds.
Or if I try to deal with the TextEditingController's value or selection property to place cursor at the end of the text, it causes more strange behaviors.
Can you provide me an example by using a TextField or a TextFormField with a TextEditingController and on onChanged() if text length is equals with 2 than insert a new character at the end and place back the cursor also at the end.
I tried these solutions but in this case they did not work:
How do you change the value inside of a textfield flutter?
Thank you!
EDIT: Example code:
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'example',
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
final TextEditingController controller = TextEditingController(text: '');
#override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
onChanged: (value) {
if (controller.text != null && controller.text.length == 2) {
controller.text = '$value/';
controller.selection = TextSelection.fromPosition(
TextPosition(offset: controller.text.length));
setState(() {});
}
},
);
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
}
The problem: If I replace the TextFormField to a TextField, it works as expected. I guess it is a bug that should be fixed.
I also found a link that in flutter version 1.20.1 and later this is an issue with TextFormFields.
https://github.com/flutter/flutter/issues/62654
TextFormField is a FormField that contains a TextField. While a Form isn't required to be its parent, using a Form makes it easier to manage multiple fields at once. You can stick with TextField if it works better and meets the requirements.

Custom dropdown widget in Flutter how to implement setState

I implemented a custom DropdownButton widget, but I don't know how to implement it's setState. I would like to pass items and selectedItem to the widget, and let it to handle it's own state. And retrieve selected item when needed by myDropdownButton.selectedItem. How I could implement it?
class MyDropdownButton extends StatefulWidget {
final String selected;
final List<MyDropdownItem> items;
MyDropdownButton({Key key, this.selected, this.items})
: super(key: key);
#override
_MyDropdownButtonState createState() => _MyDropdownButtonState();
}
class _MyDropdownButtonState extends State<MyDropdownButton> {
Widget build(BuildContext context) {
return DropdownButtonFormField(
value: widget.selected,
onChanged: (String value) {
widget.selected = value;
},
But the selected is final and cannot be modified. How to implement it?
Thank you!
There are two questions here:
Updating the widget, using setState.
Passing the value back to the widget that is using the Dropdown with a callback. Medium Article on callbacks
Firstly to have the dropdown update, you need to call a setstate on the value change. But first, you'll need to receive the value passed, usually this is done in initstate.
Second, you need to use a callback function. The class that calls this widget/class can then receive and process that value
class MyDropdownButton extends StatefulWidget {
final String selected;
final List<MyDropdownItem> items;
final Function(String) valueReturned; //callback function
MyDropdownButton({Key key, this.selected, this.items, this.valueReturned})
: super(key: key);
#override
_MyDropdownButtonState createState() => _MyDropdownButtonState();
}
class _MyDropdownButtonState extends State<MyDropdownButton> {
String sel;
#override
void initState() {
super.initState();
sel = widget.selected; //get the value passed
}
Widget build(BuildContext context) {
return DropdownButtonFormField(
value: sel
onChanged: (String value) {
setState() {
sel = value;
widget.valueReturned(value); //this will trigger the callback function
},
}
In the code that calls the widget, you will need to listen to and handle the response.
Container(
child: MyDropdownButton(items: items, selected: selected, valueReturned: _handleValueReturned))
_handleValueReturned(String value) {
thingToUpdate = value;
}
Define a local variable and initialize it in initState():
String _selected;
#override
void initState() {
super.initState();
_selected = widget.selected;
}
use setState to update your local variable as the selection changes:
onChanged: (String value) {
setState(() {_selected = value;})
}
To retrieve the value, define a getter in your class:
String get selectedItem => _selected;
You can then access the selected item using myDropdownButton.selectedItem.
For more detailed explanation on implicit and explicit getters/setters see How do getters and setters change properties in Dart?

How to Retrieve value from DropdownFormField?

I used dropdownformfield to get the gender of user in the sign up page, I created the widget in other class, I wanna know how can I control the field or retrieve the value when it changes because it doesnt have a controller unlike textformfield.
I would suggest adding an onChanged callback that can be passed into the constructor of the class containing the dropdown field.
class DropdownField extends StatelessWidget {
final Function(dynamic) onChanged;
DropdownField({#required this.onChanged});
#override
Widget build(BuildContext context) {
return DropdownButtonFormField(
onChanged: this.onChanged,
);
}
}
Then when you instantiate the class, have it manipulate something on callback.
class _OtherClassState extends State<OtherClass> {
var _selectedItem;
#override
Widget build(BuildContext context) {
return DropdownField(
onChanged: (newItem) => setState(() => this._selectedItem = newItem),
);
}
}