I have built a very simple form in flutter and I am trying to save the value of whatever is typed in the form fields to variables. This way, I can push these variables to firebase. However, nothing in the onSaved() block of the TextFormFields is being run. I have called save() on the current state of the form, but it still doesn't seem to work. Any ideas?
I have attached the code for the page below:
import 'package:flutter/material.dart';
class AddJobPage extends StatefulWidget {
const AddJobPage({Key? key}) : super(key: key);
static Future<void> show(BuildContext context) async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const AddJobPage(),
fullscreenDialog: true
));
}
@override
_AddJobPageState createState() => _AddJobPageState();
}
class _AddJobPageState extends State<AddJobPage> {
final _formKey = GlobalKey<FormState>();
//These two variables are where we will store the values of the text form fields
//before we push to firestore.
String? _name = '';
int _ratePerHour = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 2,
title: const Text("New Job"),
backgroundColor: Colors.teal.shade700,
actions: [
TextButton(
onPressed: _submit,
child: const Text(
'Save',
style: TextStyle(fontSize: 18, color: Colors.white),
)
)
],
),
body: _buildContents(),
backgroundColor: Colors.grey.shade200,
);
}
void _submit() {
if(_validateAndSave()) {
print("form saved, name: $_name, ratePerHour: $_ratePerHour");
}
}
bool _validateAndSave() {
final form = _formKey.currentState;
if(form!.validate()) {
print("the form was saved here");
form.save;
return true;
}
return false;
}
Widget _buildContents() {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: _buildForm(),
),
),
),
);
}
Widget _buildForm() {
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _buildFormChildren(),
)
);
}
List<Widget> _buildFormChildren() {
return [
TextFormField(
decoration: const InputDecoration(labelText: 'Job name'),
onSaved: (value) {
print("code doesn't reach here");
_name = value; //save the value of the text field to _name
}
),
TextFormField(
decoration: const InputDecoration(labelText: 'Rate Per Hour'),
keyboardType: const TextInputType.numberWithOptions(
signed: false,
decimal: false
),
onSaved: (value) {
_ratePerHour = int.tryParse(value!) ?? 0;
}
),
];
}
}
CodePudding user response:
You need to call the save
function.
So replace form.save;
in your code with form.save();
CodePudding user response:
replace form.save
with form.save()
and you're done. No need to worry about text controllers since you're using a text form field
CodePudding user response:
you need to add a TextEditingController to get the text from a TextFormField. Then you need to call setstate inside OnChanged, not on Onsaved so you can transfer the text to a variable. This is what your code should look like:
First you initialize a controller like this
final TextEditingController textController = TextEditingController();
String _name = "not set";
then you add the controller to your textformfield like this
TextFormField(
controller: textController ,
onChanged:(value)
{
setState(() {
_name = textController.text;
});
} ,
)
This is a complete example:
class TextFormFieldExample extends StatefulWidget {
const TextFormFieldExample({Key? key}) : super(key: key);
@override
_TextFormFieldExampleState createState() => _TextFormFieldExampleState();
}
class _TextFormFieldExampleState extends State<TextFormFieldExample> {
//Create the controller here
final TextEditingController textController = TextEditingController();
String _name = "not set";
@override
Widget build(BuildContext context) {
print(_name);
return Scaffold(
body: Material(
child: Container(
color: Colors.white,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child:TextFormField(
controller: textController ,//Attach the controller to the text form here
onChanged:(value)
{
setState(() {
_name = textController.text;//Save the text from the controller to a variable
});
} ,
),
),
),
);
}
}