I want to do a Custom TextFormField so I call it when I want, but valuedata
property inside onSave() keeps being empty after passing the data to it.
Here is the custom TextFormField:
class CustomTextField extends StatelessWidget {
CustomTextField({
Key? key,
required this.labelText,
required this.textInputType,
required this.message,
required this.valuedata,
}) : super(key: key);
final String labelText;
final TextInputType textInputType;
final String message;
String valuedata;
@override
Widget build(BuildContext context) {
return TextFormField(
onSaved: (value) {
valuedata = value!;
},
keyboardType: textInputType,
decoration: InputDecoration(
labelStyle: const TextStyle(
color: Colors.green,
),
labelText: labelText,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.0)),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.green, width: 2.0),
borderRadius: BorderRadius.circular(8.0),
)),
validator: (text) {
if (text!.isEmpty) {
return message;
} else {
return null;
}
},
);
}
}
Here where I use it:
CustomTextField(
valuedata: input.input1,
labelText: 'name',
message: 'Please enter your name',
textInputType: TextInputType.text,
),
and this is the full code where I use the CustomTextField:
class Apply extends StatefulWidget {
const Apply({Key? key}) : super(key: key);
@override
_ApplyState createState() => _ApplyState();
}
class Data {
String input1 = '';
String input2 = '';
}
class _ApplyState extends State<Apply> {
var formKey = GlobalKey<FormState>();
static Data input = Data();
var input1 = '';
var input2 = '';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Theme(
data: ThemeData(primaryColor: Colors.green),
child: Form(
key: formKey,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Les informations Personneles:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 8,
),
CustomTextField(
valuedata: input.input1,
//data: data,
labelText: 'Prenom',
message: 'Please enter your name',
textInputType: TextInputType.text,
),
const SizedBox(
height: 16,
),
CustomTextField(
valuedata: input.input2,
labelText: 'Prenom',
message: 'Please enter your name',
textInputType: TextInputType.text,
//d,
),
Row(
children: [
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
onPressed: () {
formKey.currentState!.reset();
input1 = '';
input2 = '';
setState(() {});
},
child: const Text('Clear'))),
const SizedBox(
width: 16,
),
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
),
onPressed: () {
if (formKey.currentState!.validate()) {
formKey.currentState!.save();
setState(() {});
}
},
child: const Text('show'))),
],
),
const SizedBox(
height: 16,
),
Text('Input1: ${input.input1}'),
Text('Input2: ${input.input1}'),
const SizedBox(
height: 16,
),
],
),
),
),
),
),
),
);
}
}
If you refer to the image input1 and input2 doesn't get the user Inputs. My question is, with this same approach how can make the onSave() save the values on the state?
CodePudding user response:
This is what you are looking for
class Apply extends StatefulWidget {
const Apply({Key? key}) : super(key: key);
@override
_ApplyState createState() => _ApplyState();
}
class Data {
List<String> inputs = ['',''];
}
class _ApplyState extends State<Apply> {
var formKey = GlobalKey<FormState>();
static Data input = Data();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Theme(
data: ThemeData(primaryColor: Colors.green),
child: Form(
key: formKey,
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Les informations Personneles:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(
height: 8,
),
createTextField('label1', TextInputType.datetime, 'msg', 0),
createTextField('label2', TextInputType.datetime, 'msg', 1),
Row(
children: [
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
onPressed: () {
formKey.currentState!.reset();
//input1 = '';
//input2 = '';
setState(() {});
},
child: const Text('Clear'))),
const SizedBox(
width: 16,
),
Expanded(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
),
onPressed: () {
if (formKey.currentState!.validate()) {
formKey.currentState!.save();
setState(() {});
}
},
child: const Text('show'))),
],
),
const SizedBox(
height: 16,
),
Text('Input1: ${input.inputs[0]}'),
Text('Input2: ${input.inputs[1]}'),
const SizedBox(
height: 16,
),
],
),
),
),
),
),
),
);
}
createTextField(String labelText, TextInputType textInputType, String message, int index) => TextFormField(
onSaved: (value) {
setState(() {
input.inputs[index] = value!;
});
},
keyboardType: textInputType,
decoration: InputDecoration(
labelStyle: const TextStyle(
color: Colors.green,
),
labelText: labelText,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(8.0)),
focusedBorder: OutlineInputBorder(
borderSide: const BorderSide(color: Colors.green, width: 2.0),
borderRadius: BorderRadius.circular(8.0),
)),
validator: (text) {
if (text!.isEmpty) {
return message;
} else {
return null;
}
},
);
}