Reputation: 1185
how can i set the value of a TextFormField
from a widget variable when this variable changed according to a setstate
action after building the widget and not by the initial value of this textformfeild
what i know that i can change its value by using the TextEditingController
but i have too many TextFormField
and creating the TextEditingController
take a lot of code by using the traditional way by adding them the whole widget:
1-Create a TextEditingController.
2-Connect the TextEditingController to a text field.
3-Create a function to update the latest value.
4-Listen to the controller for changes.
is there any way to build this controller and do those steps inside the code of the TextFormField
only? or another way ?
Upvotes: 1
Views: 8166
Reputation: 308
TextField(
controller: TextEditingController()..text = 'Your initial value',
onChanged: (text) => {},
)
Upvotes: 1
Reputation: 111
Do like this.
TextField( controller: TextEditingController(text: '10'), style: TextStyle( fontSize: 20, ),
Upvotes: 1
Reputation: 3986
Similar example with TextFormField
, TextEditingController
, clickable suffixIcon
for a selectDate
showDatePicker
(this is a standard material "lambda" dialog) where setState
is updating the initial set date (not by the initialValue
, rather by the controller
parameter) with a new date.
import 'package:flutter/material.dart';
class CreateOrderForm extends StatefulWidget {
const CreateOrderForm({Key? key}):super(key: key);
@override
CreateOrderFormState createState() => CreateOrderFormState();
}
class CreateOrderFormState extends State<CreateOrderForm>
{
final _formKey = GlobalKey<FormState>();
late DateTime selectedDate;
@override
void initState() {
super.initState();
selectedDate = DateTime.now();
print("initState selectedDate = ${selectedDate.toLocal()}");
}
@override
Widget build(BuildContext context) {
print("build prepare selectedDate: ${selectedDate.toLocal()}");
return Form(
key: _formKey,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextFormField(
//initialValue: "${selectedDate.toLocal()}",
controller: TextEditingController(text: "${selectedDate.toLocal()}"),
decoration: InputDecoration(
icon: Icon(Icons.event),
border: OutlineInputBorder(),
labelText: "Assignment Date & Time",
suffixIcon: IconButton(
onPressed: () => _selectDate(context),
icon: Icon(Icons.event))
),
),
const Padding(padding: EdgeInsets.only(top: 8)),
Align(
alignment: Alignment.bottomRight,
child: ElevatedButton(
onPressed: ((){}),
child: Text("Submit")),
)
],
),
),
)
);
}
_selectDate(BuildContext context) async{
await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1970),
lastDate: DateTime(9999)
).then((value){
if(value != null && value != selectedDate)
{
this.setState(() {
selectedDate = value;
print("New date ${selectedDate.toLocal()}");
});
}
});
}
}
Upvotes: 1
Reputation: 103
place controler in
TextFormField(
controller: TextEditingController(text: daytask),....
then place setstate() txt='';
like this
setState(() { txt='' }
Upvotes: 4
Reputation: 99
Best way to do this is to simply make a widget. For this one, here is the code that i would use
class StateTextField extends StatelessWidget {
final String text;
const StateTextField({Key key, this.text = ''}) : super(key: key);
@override
Widget build(BuildContext context) {
return TextField(
controller: TextEditingController(text: text),
);
}
}
that should do the work. If u want to pass the controller, u can pass it too. And to use it, just call the class in build method.
Upvotes: 2