user18134097
user18134097

Reputation:

Get values from separate TextFormField widget in flutter

I have separated my TextFormField Widget from the editing page to clear the clutter.

This is inside my CustomFormField:

class CustomFormField extends StatefulWidget {
  String? val;
  bool? isNumberPadRequired;
  CustomFormField({
    Key? key,
    this.val = '',
    this.isNumberPadRequired = false,
  }) : super(key: key);

  @override
  _CustomFormFieldState createState() => _CustomFormFieldState();
}

class _CustomFormFieldState extends State<CustomFormField> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 40,
      child: Center(
        child: TextFormField(
          initialValue: widget.val!,
          onSaved: (val) {
            print(val);
            if (val!.isNotEmpty) {
              setState(() {
                widget.val = val;
              });
            }
          },
          keyboardType: widget.isNumberPadRequired!
              ? TextInputType.number
              : TextInputType.text,
          textAlign: TextAlign.left,
          decoration: InputDecoration(
            isDense: true,
            border: OutlineInputBorder(),
            contentPadding: EdgeInsets.symmetric(
              vertical: 25.0,
              horizontal: 10.0,
            ),
            focusedBorder: OutlineInputBorder(
              borderSide: BorderSide(
                color: CustomColors.secondary,
                width: 2,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

And inside my EditProfilePage I have some string values like name, email and number with the current values:

String email = user.email; // [email protected]
String name = user.name; // John Doe

And inside the Form:

return Form(
  key: _formKey,
  autovalidateMode: AutovalidateMode.onUserInteraction,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      _buildName(),
      ....
    ],
  ),
);

Widget _buildName() {
  return FormFieldWrapper(
    label: "Name",
    child: CustomFormField(
      val: firstName, // newly typed name: Jane Monroe
    ),
  );
}

But when I try to call the _handleUpdate():

  _updateProfile() async {
    (_formKey.currentState as FormState).save();
    print(name);
  }

I am getting the old values i.e John Doe.

Upvotes: 2

Views: 683

Answers (1)

Salih Can
Salih Can

Reputation: 1783

You should add the String Function argument to your custom textfield. When call saves method you should call this argument, for the update name or whatever variable.

Example;

class CustomFormField extends StatefulWidget {
  String? val;
  bool? isNumberPadRequired;
  final Fuction(String savedValue) onSaved;

  CustomFormField({
    Key? key,
    this.val = '',
    required this.onSaved,
    this.isNumberPadRequired = false,
  }) : super(key: key);

  @override
  _CustomFormFieldState createState() => _CustomFormFieldState();
}

class _CustomFormFieldState extends State<CustomFormField> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 40,
      child: Center(
        child: TextFormField(
          initialValue: widget.val!,
          onSaved: (val) {
            print(val);
            if (val!.isNotEmpty) {
              widget.onSaved(val);
            }
          },
          keyboardType: widget.isNumberPadRequired!
              ? TextInputType.number
              : TextInputType.text,
          textAlign: TextAlign.left,
          decoration: InputDecoration(
            isDense: true,
            border: OutlineInputBorder(),
            contentPadding: EdgeInsets.symmetric(
              vertical: 25.0,
              horizontal: 10.0,
            ),
            focusedBorder: OutlineInputBorder(
              borderSide: BorderSide(
                color: CustomColors.secondary,
                width: 2,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

and should implement inside Form widget;

return Form(
  key: _formKey,
  autovalidateMode: AutovalidateMode.onUserInteraction,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      _buildName(),
      ....
    ],
  ),
);

Widget _buildName() {
  return FormFieldWrapper(
    label: "Name",
    child: CustomFormField(
      val: firstName, // newly typed name: Jane Monroe
      onSaved: (String savedValue){
         name = savedValue;
      },
    ),
  );
}

Upvotes: 1

Related Questions