Only last input data is showing in the lists, Whenever I input the new value in the form, the new data is updated but previous one is updated too. This is how the output is showing in the lists:
here is the code of the file model.dart:
class Model {
String firstName = "";
String lastName = "";
String email = "";
String password = "";
Model({this.firstName, this.lastName, this.email, this.password});
}
and here is my main file on which I am inserting the data into form, and showing the output in the lists on the same screen:
class DialogForm extends StatefulWidget {
List<Model> models = <Model>[];
Model tempModel = Model();
final newModel = Model();
DialogForm();
@override
State<DialogForm> createState() => _ResultState();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<Model>('model', tempModel));
}
}
class _ResultState extends State<DialogForm> {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return (Scaffold(
appBar: AppBar(title: Text('Successful')),
body: Container(
margin: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: ListView.builder(
itemCount: widget.models.length,
itemBuilder: (context, index) => Card(
elevation: 6,
margin: EdgeInsets.all(10),
child: ListTile(
title: Text(widget.models[index].firstName),
subtitle: Text(widget.models[index].lastName),
trailing: Text(widget.models[index].email),
)
)
)
),
Align(
child: RaisedButton(
child: Text('Click Me!'),
onPressed: (){
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
content: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
right: -40,
top: -40,
child: InkResponse(
onTap: () {
Navigator.of(context).pop();
},
child: CircleAvatar(
child: Icon(Icons.close),
backgroundColor: Colors.red,
),
),
),
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: EdgeInsets.all(8.0),
child: MyTextFormField(
hintText: 'First Name',
validator: (String value) {
if (value.isEmpty) {
return 'Enter your first name';
}
return null;
},
onSaved: (String value) {
widget.tempModel.firstName = value;
},
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: MyTextFormField(
hintText: 'Last Name',
validator: (String value) {
if (value.isEmpty) {
return 'Enter your last name';
}
return null;
},
onSaved: (String value) {
print(value);
widget.tempModel.lastName = value;
},
),
),
Padding(
padding: EdgeInsets.all(8.0),
child: MyTextFormField(
hintText: 'Enter email',
isEmail: true,
// validator: (String value) {
// if (!validator.isEmail(value)) {
// return 'Please enter a valid email';
// }
// return null;
// },
onSaved: (String value) {
widget.tempModel.email = value;
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: RaisedButton(
child: Text("Submit"),
onPressed: () {
// var m = widget.tempModel;
// print(m.firstName "" m.lastName "" m.email);
// return;
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
// var m = widget.tempModel;
// print(m.firstName "" m.lastName "" m.email);
widget.models.add(widget.tempModel);
setState(() {
widget.models = widget.models;
// widget.tempModel.add(new widget.models());
}
);
Navigator.of(context).pop();
}
},
),
)
],
)
),
],
),
);
}
);
}
),
alignment: Alignment.bottomRight,
),
],
),
),
)
);
}
}
class MyTextFormField extends StatelessWidget {
final String hintText;
final Function validator;
final Function onSaved;
final bool isPassword;
final bool isEmail;
MyTextFormField({
this.hintText,
this.validator,
this.onSaved,
this.isPassword = false,
this.isEmail = false,
});
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.all(15.0),
border: InputBorder.none,
filled: true,
fillColor: Colors.grey[200],
),
obscureText: isPassword ? true : false,
validator: validator,
onSaved: onSaved,
keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text,
),
);
}
}
CodePudding user response:
First of all, I believe you should move the following variables:
List<Model> models = <Model>[];
Model tempModel = Model();
final newModel = Model();
into the state class because it makes more sense for them to be there, with the exception maybe of newModel
, but I will address newModel
in a second.
You never use newModel
. ever why not get rid of it???
Ok, now, you could make a factory constructor for your model like this:
class Model {
String firstName = "";
String lastName = "";
String email = "";
String password = "";
Model({this.firstName, this.lastName, this.email, this.password});
factory Model.fromModel(Model model) {
return Model(firstName: model.firstName, lastName: model.lastName, email: model.email, password: model.password);
}
}
and when adding a new model:
models.add(Model.fromModel(tempModel));
Hopefully, these changes can solve your issue
EDIT
To remove an item from the list, you could do something similar to this:
ListTile(
title: Row(
children: [
TextButton(
child: Icon(Icons.delete),
onPressed: () {
models.removeAt(index);
setState(() => models = models):
},
Text(models[index].firstName),
]
),
subtitle: Text(models[index].lastName),
trailing: Text(models[index].email),
)