I'm trying to create an "Edit Profile" page where I'm loading all the user data and letting the user modify it. However, using both the value
and text
properties on the TextEditingController
result in being unable to modify the data in the TextFormField
. I can add to the beginning of it, but I cannot delete any characters from it.
To elaborate on this behavior further, in the screenshot below, I can type more into the field (as I did the "Asdf"), but from where the cursor is, I cannot move the cursor to the right or delete the "F" or any of the characters placed there originally.
In the OnSaved
function of the TextFormField
, the value
param is the full text of the form at the time of submission, in this case, "AsdfFrederick".
Here's my code:
import 'dart:async';
import 'package:flutter/material.dart';
import '../models/user.dart';
class EditProfileView extends StatefulWidget {
@override
_EditProfileViewState createState() => new _EditProfileViewState();
}
class _EditProfileViewState extends State<EditProfileView> {
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
void _handleSubmitted() {
final FormState form = _formKey.currentState;
if (!form.validate()) {
} else {
form.save();
User.instance.save().then((result) {
print("Saving done: ${result}.");
Navigator.pop(context);
});
}
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final DateTime today = new DateTime.now();
// controllers for form text controllers
final TextEditingController _firstNameController =
new TextEditingController();
//_firstNameController.value = new TextEditingValue(text: User.instance.first_name);
_firstNameController.text = User.instance.first_name;
final TextEditingController _lastNameController =
new TextEditingController();
_lastNameController.text = User.instance.last_name;
return new Scaffold(
appBar: new AppBar(title: const Text('Edit Profile'), actions: <Widget>[
new Container(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 5.0, 10.0),
child: new MaterialButton(
color: themeData.primaryColor,
textColor: themeData.secondaryHeaderColor,
child: new Text('Save'),
onPressed: () {
_handleSubmitted();
Navigator.pop(context);
},
))
]),
body: new Form(
key: _formKey,
autovalidate: _autovalidate,
onWillPop: _warnUserAboutInvalidData,
child: new ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
new Container(
child: new TextFormField(
decoration: const InputDecoration(labelText: "First Name", hintText: "What do people call you?"),
autocorrect: false,
controller: _firstNameController,
onSaved: (String value) {
User.instance.first_name = value;
},
),
),
new Container(
child: new TextFormField(
decoration: const InputDecoration(labelText: "Last Name"),
autocorrect: false,
controller: _lastNameController,
onSaved: (String value) {
User.instance.last_name = value;
},
),
),
],
)));
}
}
Here's flutter doctor
:
% flutter doctor
[✓] Flutter (on Mac OS X 10.12.6 16G29, locale en-US, channel alpha)
• Flutter at /Users/frederickcook/flutter
• Framework revision 701d534ba9 (2 weeks ago), 2017-09-12 14:01:51 -0700
• Engine revision 31d03de019
• Tools Dart version 1.25.0-dev.11.0
[✓] Android toolchain - develop for Android devices (Android SDK 26.0.0)
• Android SDK at /Users/frederickcook/Library/Android/sdk
• Platform android-26, build-tools 26.0.0
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.0)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 9.0, Build version 9A235
• ios-deploy 1.9.2
• CocoaPods version 1.2.1
[✓] Android Studio (version 2.3)
• Android Studio at /Applications/Android Studio.app/Contents
• Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)
[✓] IntelliJ IDEA Community Edition (version 2017.2.5)
• Flutter plugin version 17.0
• Dart plugin version 172.4155.35
[✓] Connected devices
• iPhone 7 • 2AE532E3-5B4B-4D8D-8CFB-F54C3BF6F8EE • ios • iOS 11.0 (simulator)
Using initialValue:
property works well with TextFormField
.
Figured it out: switched from TextFormField
to TextField
, created local variables to store changes to the fields, and used initState
to set initial form values instead of doing it in build
.
import 'dart:async';
import 'package:flutter/material.dart';
import '../models/user.dart';
class EditProfileView extends StatefulWidget {
@override
_EditProfileViewState createState() => new _EditProfileViewState();
}
class _EditProfileViewState extends State<EditProfileView> {
final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
void _handleSubmitted() {
final FormState form = _formKey.currentState;
if (!form.validate()) {
_autovalidate = true; // Start validating on every change.
showInSnackBar('Please fix the errors in red before submitting.');
} else {
showInSnackBar('snackchat');
User.instance.first_name = firstName;
User.instance.last_name = lastName;
User.instance.save().then((result) {
print("Saving done: ${result}.");
});
}
}
// controllers for form text controllers
final TextEditingController _firstNameController = new TextEditingController();
String firstName = User.instance.first_name;
final TextEditingController _lastNameController = new TextEditingController();
String lastName = User.instance.last_name;
@override
void initState() {
_firstNameController.text = firstName;
_lastNameController.text = lastName;
return super.initState();
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final DateTime today = new DateTime.now();
return new Scaffold(
appBar: new AppBar(title: const Text('Edit Profile'), actions: <Widget>[
new Container(
padding: const EdgeInsets.fromLTRB(0.0, 10.0, 5.0, 10.0),
child: new MaterialButton(
color: themeData.primaryColor,
textColor: themeData.secondaryHeaderColor,
child: new Text('Save'),
onPressed: () {
_handleSubmitted();
Navigator.pop(context);
},
))
]),
body: new Form(
key: _formKey,
autovalidate: _autovalidate,
onWillPop: _warnUserAboutInvalidData,
child: new ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
new Container(
child: new TextField(
decoration: const InputDecoration(labelText: "First Name", hintText: "What do people call you?"),
autocorrect: false,
controller: _firstNameController,
onChanged: (String value) {
firstName = value;
},
),
),
new Container(
child: new TextField(
decoration: const InputDecoration(labelText: "Last Name"),
autocorrect: false,
controller: _lastNameController,
onChanged: (String value) {
lastName = value;
},
),
),
],
)));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With