Reputation: 6974
I'm new on Flutter. I'm trying to disabled button while I compile textFormField and it is invalid. My problem is that it works only if I click on "confirm" on keyboard and not while I compile my input. So would like disable button while I write the input.
I've done a pastebin for example:
class AddCartButton extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return AddCartButtonState();
}
}
class AddCartButtonState extends State<AddCartButton>{
TextEditingController myController = TextEditingController();
bool isValid = false;
@override
Widget build(BuildContext context) {
void _addToCart(){
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("QUANTITY"),
content: Column(
children: <Widget>[
TextFormField(
controller: myController,
decoration: new InputDecoration(labelText: "quantity"),
keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: <TextInputFormatter>[],
autovalidate: true,
validator: (value) {
if (value.isEmpty) {
isValid = false;
return "the quantity cannot be empty";
} else if (double.tryParse(value) == null) {
isValid = false;
return "the quantity must be valid number";
} else {
isValid = true;
return null;
}
}
)
],
),
actions: <Widget>[
FlatButton(
disabledTextColor: Colors.grey,
child: Text("add"),
onPressed: isValid ? () { print("is valid"); }: null
)
],
);
},
);
}
}
}
Upvotes: 1
Views: 3596
Reputation: 2982
You can use this method .
bool isEnable = false;
void validateButton() {
bool isValid = true;
isValid = userEmail.isNotEmpty &&
userPassword.isNotEmpty &&
validateEmail(userEmail) &&
userPassword.length >= 8;
setState(() {
isEnable = isValid;
});
}
now in your Textfield onChanged method you have to call this function
like This
onChanged: (email) {
userEmail = email;
setState(() {});
validateButton();
},
and in your Login Button
isEnable?ActiveButton():DisableButton()
Upvotes: 0
Reputation: 1561
You can use addListener()
function on your TextEditingController myController
.
myController.addListener((){
//With this, you can "listen" all the changes on your text while
//you are typing on input
print("value: ${myController.text}");
//use setState to rebuild the widget
setState(() {
//you can check here if your text is valid or no
//_isValidText() is just an invented function that returns
//a boolean representing if the text is valid or not
if(_isValidText(myController.text)) isValid = true;
else isValid = false;
});
});
Upvotes: 2
Reputation: 9635
If I understood what you want to achieve the following code works for you. The conditions I set are the same as your validation rules:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController _textEditingController = TextEditingController();
Function _submitFunction;
// We need a reusable timer and it needs to not be null so that we can cancel it from th start.
Timer _timer = Timer(Duration(milliseconds: 1), () => print('initialTimer'));
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Auto disable button'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
controller: _textEditingController,
onChanged: (text) {
setState(() {
_submitFunction = null;
});
restartTimer();
},
),
RaisedButton(
child: Text('Submit'),
onPressed: _submitFunction,
),
],
),
),
)
);
}
void submitForm(){
print(_textEditingController.text);
}
void enableButton(){
if(_textEditingController.text != ''){
setState(() {
_submitFunction = submitForm;
});
}
}
void restartTimer(){
_timer.cancel();
_timer = Timer(Duration(milliseconds: 1500), enableButton);
}
}
Upvotes: 0