Home > Net >  Create a Statefule widget with a TextFormFiled inside
Create a Statefule widget with a TextFormFiled inside

Time:04-12

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;
                   }
         },
)
  • Related