4

I'm new to flutter and I'm trying to make a button disabled as long as some text fields are empty, so i made 3 textcontrollers to act as a controller for the 3 text fields and i made a function to check the function is:

bool isEmpty(){
    setState(() {
          if(textEditingController.text!=" "&&textEditingController2.text!=" "&& textEditingController3.text!=" "){
            isButtonEnabled=true;


          }
        });
       return isButtonEnabled; 
  }

And the code for the text field is:

TextField(
                  onSubmitted:null,

                  controller: textEditingController3,


                )

Then i write the code for the button as follows: Center(

  child: RaisedButton(
         child: Text("Button 1",style: TextStyle(color:Colors.white),),
          onPressed:isButtonEnabled?(){ print("enabled");}:null,
          color: Colors.red,

            ),

The problem is the button remains disabled even after i write in the text fields. Any idea? Thanks in advance. EDIT: thanks to @diegoveloper answer this worked, but what if i wanted to put intital value and i want the button to be enabled only if the text fields have values for the text fields as following :

@override
  void initState() {
    super.initState();
   textEditingController  = new TextEditingController(text: name);
      textEditingController2  = new TextEditingController(text: email);
         textEditingController3  = new TextEditingController(text: " place");


  }

Then i updated the isEmpty method to be:

bool isEmpty(){
    setState(() {
          if((textEditingController.text!=" ")&&(textEditingController2.text!=" ")&& (textEditingController3.text!=" ")&&(textEditingController!=null)&&(textEditingController2!=null)&&(textEditingController3!=null)){
            isButtonEnabled=true;



          }
          else{
                        isButtonEnabled=false;

          }
        });
       return isButtonEnabled; 
  }

The problem is despite of the intials values i gave to text fields the button is still disabled, also when i edit the 3 values of textfields the button is enabled, but if i deleted the text (in which i think it's meant by null) the button is still disabled.

Mee
  • 1,413
  • 5
  • 24
  • 40

3 Answers3

17

You don't need any additional libraries to do that. Flutter has it out-of-the-box and you can make sure you're not going to rebuild the whole tree on each keystroke.

TextEditingController extends ValueNotifier<TextEditingValue> which means you can utilize ValueListenableBuilder from material package to listen to text changes.

class MyWidget extends StatelessWidget {
  final TextEditingController _inputController = TextEditingController();

  @override
  void dispose() {
    _inputController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      TextField(controller: _inputController),
      ValueListenableBuilder<TextEditingValue>(
        valueListenable: _inputController,
        builder: (context, value, child) {
          return ElevatedButton(
            onPressed: value.text.isNotEmpty ? () {} : null,
            child: Text('I am disabled when text is empty'),
          );
        },
      ),
    ]);
  }
}
Kyrylo Zapylaiev
  • 682
  • 1
  • 8
  • 15
  • this is so helpful, simple and very clean, plus you dont have to rebuild your widget tree on each keystroke indeed, thank you – besim Feb 01 '23 at 21:33
3

You could read more about TextField here: https://flutter.io/cookbook/forms/text-field-changes/

So you have two options :

1 - Listen for changes on each TextEditingController and call to your method isEmpty()

2 - Add the onChanged callback on each TextField you want to listen the changes.

Option 2

TextField(
  onSubmitted: null,
  onChanged: (val) {
    isEmpty();
  },
  controller: textEditingController3,
)

Note: don't forget to add the ELSE condition to your isEmpty method.

Edit

Modify your initState method to check if your button is enable (refactor this code please)

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

    textEditingController = TextEditingController(text: "name");
    textEditingController2 = TextEditingController(text: "email");
    textEditingController3 = TextEditingController(text: "place");

    if ((textEditingController.text.trim() != "") && (textEditingController2.text.trim() != "") && (textEditingController3.text.trim() != "")) {
        isButtonEnabled = true;
    } else {
        isButtonEnabled = false;
    }
}
diegoveloper
  • 93,875
  • 20
  • 236
  • 194
  • Thank you for your response, this worked for the first time i write in the text field, but when i delete the text i put space in the text field again it did not turn in to disabled i don't know why? – Mee Sep 23 '18 at 18:34
  • Could you update your question with your latest code? I see that you have 3 texteditingcontroller – diegoveloper Sep 23 '18 at 18:35
  • Oh wait, in your isEmpty method you have an if condition add and ELSE and set isButtonEnabled false – diegoveloper Sep 23 '18 at 18:37
  • Thank you this worked, could you please check the edit? i have another problem – Mee Sep 23 '18 at 18:53
  • I don't understand your question , what do you need? – diegoveloper Sep 23 '18 at 18:59
  • change your conditions text != "" <=== not text!= " " <== blank space – diegoveloper Sep 23 '18 at 19:02
  • I need to put initial value for my text fields, and i already did in the initState, so i expect that the button has to be enabled as the textfield is not have spaces or empty it turns into enabled only if i pressed on one of them as if i edit them, also i want to check if the text field is empty i would like to make the the button disabled also if it is empty, but the case here is when i delete all the text of any of the textfields the button does not turn into disabled – Mee Sep 23 '18 at 19:03
  • that's because your condition is wrong text != "" is ok , not text != " " – diegoveloper Sep 23 '18 at 19:04
  • or you could try : text.trim() != "" – diegoveloper Sep 23 '18 at 19:05
  • and on your initState use the same conditions but you can not use setState there. if (...your conditions ) { isButtonEnabled = true; } else { isButtonEnabled = false; } but don't use setState, you'll have to refactor your code – diegoveloper Sep 23 '18 at 19:06
  • Yes! i thought "" will equal to null, thank you for your help, but the only problem left is that's when i put initial values for the controller i expected the button to be enabled because the text is neither blank or space but the button appear initially disabled?! – Mee Sep 23 '18 at 19:08
1

You can use nested TextEditingWatchers

Morad
  • 2,761
  • 21
  • 29