Iniisking
Iniisking

Reputation: 57

How to make a button inactive until a required field is filled in properly in flutter

I want to make a particular button inactive and a different color until all the required fields filled properly, I also want there to be a message under the textfield telling the user to fill the field correctly if they aren't. This is what I have at the moment: [![This is what I have at the moment][1]][1]

But I want something like this:

This is my code for the textfield:

TextField(
                  // controller:
                  obscureText: false,
                  maxLines: null,
                  keyboardType: TextInputType.emailAddress,
                  decoration: InputDecoration(
                    border: const OutlineInputBorder(),
                    labelText: "Email Address",
                    labelStyle: TextStyle(fontSize: 20, color: Colors.grey),
                    floatingLabelStyle:
                        TextStyle(color: Colors.black, fontSize: 20),
                    hintText: 'Email Address',
                    hintStyle: TextStyle(fontSize: 0.5),
                    isDense: true,
                    enabledBorder: OutlineInputBorder(
                      borderSide:
                          const BorderSide(width: 2.0, color: Colors.grey),
                      borderRadius: BorderRadius.circular(7),
                    ),
                    focusedBorder: OutlineInputBorder(
                        borderSide:
                            const BorderSide(color: Colors.green, width: 2.0),
                        borderRadius: BorderRadius.circular(7)),
                  ),
                  onChanged: (value) {
                    setState(() {
                      _email = value.trim();
                    });
                  },
                ),

And this is my code for the button:

GestureDetector(
                  onTap: (() {}),
                  child: Container(
                    child: Center(
                      child: Padding(
                        padding: const EdgeInsets.all(20),
                        child: Text(
                          "Continue",
                          style: TextStyle(fontSize: 19, color: Colors.white),
                        ),
                      ),
                    ),
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(50),
                        color: Colors.green),
                  ),
                ),

Upvotes: -1

Views: 299

Answers (4)

user18309290
user18309290

Reputation: 8380

Use Form to validate fields. onChanged is called when one of the fields changes, so set the state there. Disable button by setting null for onPressed as long as form is invalid. Use AutovalidateMode.always on TextFormField to enable validation without user interaction.

class MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();
  bool _isValid = false;

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      onChanged: () {
        setState(() => _isValid = _formKey.currentState!.validate());
      },
      child: Column(
        children: [
          TextFormField(
            autofocus: true,
            autovalidateMode: AutovalidateMode.always,
            validator: (value) => (value == null || value.isEmpty)
                ? 'Error'
                : null,
          ),
          ElevatedButton(
            onPressed: _isValid ? () {} : null,
            child: const Text('Submit'),
          ),
        ],
      ),
    );
  }
}

Upvotes: 0

Mahesh Gv
Mahesh Gv

Reputation: 1103

check this working fine

   final emailController = TextEditingController();


  // email text field
   TextFormField(
                  controller: emailController,
                  decoration: InputDecoration(
                    labelText: "Name",
                    labelStyle: TextStyle(
                      color: Colors.lightGreen
                    ),
                    errorStyle: TextStyle(
                      color: Colors.black
                    ),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(5.0)
                    )
                  ),
                  validator: (value){
                    if(value == null || value == ''){
                      return "Enter name";
                    }
                  },
                ) 



// button
           GestureDetector(
              onTap: (() {
                if (emailController.text.toString().isNotEmpty) {
                  //todo
                } else {
                  print("please enter email");
                }
              }),
              child: Container(
                child: Center(
                  child: Padding(
                    padding: const EdgeInsets.all(20),
                    child: Text(
                      "Continue",
                      style: TextStyle(fontSize: 19, color:emailController.text.toString().isNotEmpty? Colors.green: Colors.grey),
                    ),
                  ),
                ),
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(50),
                    color: Colors.green),
              ),
            ),

Upvotes: 0

Sabahat Hussain Qureshi
Sabahat Hussain Qureshi

Reputation: 1364

Add one bool type varaible... and check textfield value is valid like in example bool value is true and button colors is change and clickable

TextField(
  // controller:
  obscureText: false,
  maxLines: null,
  keyboardType: TextInputType.emailAddress,
  decoration: InputDecoration(
    border: const OutlineInputBorder(),
    labelText: "Email Address",
    labelStyle: TextStyle(fontSize: 20, color: Colors.grey),
    floatingLabelStyle:
    TextStyle(color: Colors.black, fontSize: 20),
    hintText: 'Email Address',
    hintStyle: TextStyle(fontSize: 0.5),
    isDense: true,
    enabledBorder: OutlineInputBorder(
      borderSide:
      const BorderSide(width: 2.0, color: Colors.grey),
      borderRadius: BorderRadius.circular(7),
    ),
    focusedBorder: OutlineInputBorder(
        borderSide:
        const BorderSide(color: Colors.green, width: 2.0),
        borderRadius: BorderRadius.circular(7)),
  ),
  onChanged: (value) {
    if(value.length>6) {
      setState(() {
        enableButton = true;
      });
    }else {
      setState(() {
        enableButton = false;
      });
    }
  },
),
GestureDetector(
  onTap: (() {
    if(enableButton){
      //do what you want
    }
  }),
  child: Container(
    child: Center(
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Text(
          "Continue",
          style: TextStyle(fontSize: 19, color: Colors.white),
        ),
      ),
    ),
    decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(50),
        color: enableButton ? Colors.green : Colors.grey
    ),
  ),
),

Upvotes: 0

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63864

Create state bool to control onPressed active mode, and listen changes on TextFiled and update the bool.

late final TextEditingController controller = TextEditingController()
    ..addListener(() {
      // your logic
      if (controller.text == "asd") {
        isValid = true;
      } else {
        isValid = false;
      }

      setState(() {});
    });

  bool isValid = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          TextFormField(
            controller: controller,
          ),
          ElevatedButton(
              onPressed: isValid
                  ? () {
//your operation
                    }
                  : null,
              child: Text("login")),
        ],
      ),
    );
  }
}

Upvotes: 0

Related Questions