Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create resuable textfield with validator in flutter

I am creating a login form which has username and password field, i want to add validation when user skip any field. I have created this reusable textfield.

class RoundedInputField extends StatelessWidget {
  final String hintText;
  final ValueChanged<String> onChanged;
  final TextEditingController controller;
  final FormFieldValidator validate;
  const RoundedInputField({Key key, this.hintText,
    this.onChanged,
   this.controller,this.validate,
 
  })
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextFieldContainer(
      child: TextFormField(
        onChanged: onChanged,            
        controller: TextEditingController(),
        validator: validate,
        decoration: InputDecoration(
          hintText: hintText,
          border: InputBorder.none,
        ),
      ),
    );
  }
}

and calling it like this

 RoundedInputField(hintText: "Username",icon: Icons.email,fontsize: 20,
                controller: TextEditingController(text: user.username),
                onChanged: (value){
                  user.username=value;
                },
                validate: (value){
                  if(value.isEmpty){
                    return "This field is required";
                  }
                },
                ),

but validator property is not working properly, here it is.

enter image description here

please help if anyone know how to fix it!

like image 706
TimeToCode Avatar asked Sep 11 '25 07:09

TimeToCode


2 Answers

I have been using TextFormField in a reusable way like this , it has served me for all the purposes i needed , i think it works for your case too

class BoxTextField extends StatelessWidget {
  final TextEditingController controller;
  final FormFieldValidator<String> validator;
  final bool obsecure;
  final bool readOnly;
  final VoidCallback onTap;
  final VoidCallback onEditingCompleted;
  final TextInputType keyboardType;
  final ValueChanged<String> onChanged;
  final bool isMulti;
  final bool autofocus;
  final bool enabled;
  final String errorText;
  final String label;
  final Widget suffix;
  final Widget prefix;

  BoxTextField(
      {Key key,
      this.controller,
      this.validator,
      this.keyboardType = TextInputType.text,
      this.obsecure = false,
      this.onTap,
      this.isMulti = false,
      this.readOnly = false,
      this.autofocus = false,
      this.errorText,
      @required this.label,
      this.suffix,
      this.prefix,
      this.enabled = true,
      this.onEditingCompleted,
      this.onChanged})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.symmetric(vertical: 4),
      child: TextFormField(
          onChanged: onChanged,
          onEditingComplete: onEditingCompleted,
          autofocus: autofocus,
          minLines: isMulti ? 4 : 1,
          maxLines: isMulti ? null : 1,
          onTap: onTap,
          enabled: enabled,
          readOnly: readOnly,
          obscureText: obsecure,
          keyboardType: keyboardType,
          controller: controller,
          decoration: InputDecoration(
            errorText: errorText,
            prefixIcon: prefix,
            suffixIcon: suffix,
            labelStyle: TextStyle(fontSize: lableFontSize()),
            labelText: label,
            hintStyle: TextStyle(color: Colors.blueGrey, fontSize: 15),
            contentPadding: EdgeInsets.symmetric(vertical: 8, horizontal: 20),
            enabledBorder: textFieldfocused(),
            border: textFieldfocused(),
            focusedBorder: textFieldfocused(),
            errorBorder: errorrTextFieldBorder(),
            focusedErrorBorder: errorrTextFieldBorder(),
          ),
          validator: validator),
    );
  }
}

This is the Usage

class LoginScreen extends StatefulWidget {
  @override
  _LoginScreenState createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
  TextEditingController _emailPhone = new TextEditingController();
  TextEditingController _password = new TextEditingController();

  GlobalKey<FormState> _formKey = new GlobalKey<FormState>();

  @override
  void initState() {
    super.initState();
  }

  String loginError;
  bool loggingIn = false;

  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: [
        SliverList(
            delegate: SliverChildListDelegate([
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 20.0),
            child: Form(
                key: _formKey,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    SizedBox(
                      height: 50,
                    ),
                    BoxTextField(
                      validator: (str) {
                        if (str.isEmpty) {
                          return tr('common.required');
                        }

                        return null;
                      },
                      controller: _emailPhone,
                      label: tr('login.username'),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    BoxTextField(
                      label: tr('login.password'),
                      controller: _password,
                      obsecure: true,
                      validator: (str) {
                        if (str.isEmpty) {
                          return tr('common.required');
                        }

                        return null;
                      },
                    ),
         Center(
                        child: BoxButton(
                      loading: loggingIn,
                      lable: tr('login.btn'),
                      onPressed: () {
                          
                            },
                    )),
                  ],
                )),
          )
        ]))
      ],
    );
  }
}
like image 109
Pompidou Avatar answered Sep 13 '25 22:09

Pompidou


Replace your code and try this:

RoundedInputField(
              hintText: "Username",
              icon: Icons.email,
              fontsize: 20,
              controller: TextEditingController(text: user.username),
              onChanged: (value) {
                user.username = value;
              },
              validate: (value) {
                if (value.isEmpty) {
                  return "This field is required";
                }
                return null;
              },
            ),
like image 27
Taha Asif Avatar answered Sep 13 '25 22:09

Taha Asif