I have an application that has a lot of forms with lots of UI changes.
Everytime I add a TextFormField
to a form, I have to add so many lines of code:
Widget usernameCodeTextFiled() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _usernameTextController,
keyboardType: TextInputType.text,
onChanged: (_) => setState(() {}),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Username',
hintText: 'Enter your username',
errorText: _submitted
? usernameValidationMessage(_usernameTextController.text)
: null,
),
),
);
}
So I decided to create a Stateful widget
with a TextFormField
and its layout and use that instead of directly using TextFormField
:
class TextEntry extends StatefulWidget {
//...
@override
State<TextEntry> createState() => _TextEntryState();
}
class _TextEntryState extends State<TextEntry> {
// ...
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _textController,
keyboardType: _keyboardType,
onChanged: _onChanged,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: _labelText,
hintText: _hintText,
errorText: _errorMessage,
),
),
);
}
}
This resulted a much cleaner and more reusable code:
//...
TextEntry(
textController: _usernameTextController,
keyboardType: TextInputType.text,
onChanged: (_) => setState(() {}),
labelText: 'Username',
hintText: 'Enter your username',
errorMessage: _submitted
? usernameValidationMessage(_usernameTextController.text)
: null,
),
//...
The only problem I have is that form validation will not work this way. How can I enable form validation for my TextEntry
widget?
CodePudding user response:
You can pass the validation function, like final String? Function(String?)? customValidator;
and pass it to the widget,
TextFormField(
validator: customValidator,
...
)
and pass it from the parent widget like,
TextEntry(
customValidator: (v) {
...
}
)
I'd suggest to replace the StatefulWidget
with StatelessWidget
as you can pass on the controller
from the parent widget, and add another parameter like customValidator
to improve performance.
CodePudding user response:
you have to define validator in textEntry like this
final String? Function(String?)? validator;
in
TextFormField(
validator: validator,
)
You can use like this
TextEntry(
validator: (value) {
if (value!.isEmpty) {
return StringProvider.pleaseEnterPass;
} else if (value.length < 8) {
return StringProvider.passwordLength;
}
},
)