I tried to put two conditions with the values of an email and a password in order to activate my button only if the two conditions are validated but it is not working because I think my syntax is written in a bad way.
Can you help me to resolve this problem please ?
Plus I have no error messages except the fact that the button doesn't navigate to the HomePage like it lost its fonction.
This is my code
child: FlatButton(
padding: EdgeInsets.symmetric(vertical: 14, horizontal: 40),
color: DarkTurquoise,
onPressed: _password.length < 6 ? null :() {
!emailRegex.hasMatch(_email) ? null : () {
if (_formKey.currentState!.validate()) {
print(_email);
print(_password);
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),
),
);
};
},
If you need to validate two conditions same time, use '&&' operator.
_password.length < 6 && !emailRegex.hasMatch(_email) ? <do something> : <do someting>
child: FlatButton(
padding: EdgeInsets.symmetric(vertical: 14, horizontal: 40),
color: DarkTurquoise,
onPressed: _password.length < 6 && !emailRegex.hasMatch(_email) ? null : () {
if (_formKey.currentState!.validate()) {
print(_email);
print(_password);
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),
),
);
},
),
use this:
onPressed: ()=>{
if (_formKey.currentState!.validate()) {
if(_password.length >= 6 && emailRegex.hasMatch(_email)){
// put your code here!
}
}
}
In flutter, if you want a button to be greyed out or not clickable, you give null to onPressed, which is what is happening in your case based on the condition saying if password < 6.
What happens is when the widget is build, it reaches the line of onPressed, applies the condition you gave it, and it discovers that indeed the password is <6, because no characters have been entered yet.
The widget is built now, and what is done is done.
After you start entering letters, the length becomes longer than 6, but the widget has already been built and you didn't trigger your UI to update and rebuild the button.
What you can do, is to move the null inside your logic, this will not grey out the button, but when you tap it and the conditions fails, nothing happens, like this:
onPressed: () {
if( _password.length >= 6) {
if(emailRegex.hasMatch(_email)){
if (_formKey.currentState!.validate()) {
print(_email);
print(_password);
//I moved the curly brace which was here to the end of the function,
//because I think you only want to navigate if the validation is true, not whenever it is pressed.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HomeScreen(),),
);
};
}, //<= new curly brace
}
This is not the right way.
Textfield validation in Flutter
Hope you can get your answer by referring to this article.
Also you can make one function for check password length and like that and create bool true or false and that bool is useful for enable and disable button as well.
Related
I want to hide the first alert dialog when I call showDialog() from it. After that when I close the second dialog I want the first dialog was visible again. How I can achieve this?
Before you call second dialog, use Navigator.of(context).pop() to close first dialog. Then, in the second one, you have functions then((value) {...}) or whenComplete(() {...}), inside that you can use it to re-open first dialog.
That's strange that you want to close first one, why don't you just leave it alone and let the second lies on it?
You can create common dialog to show data. if its already showing then just update data only.
showDialog return a future and you can pass data from dialog. The concept is here passing some flag to open the second dialog.
onPressed: () async {
final data = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: ElevatedButton(
onPressed: () {
Navigator.of(context)
.pop(true); // true for to show second dialog
},
child: Text("open Second dialog"),
),
);
});
if (data == true) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("Second dialog"),
);
});
}
},
I am working on a music player, and on pressing next button I want to perform two functions one is to add song to the queue and another function is used to trigger the plugin method of 'addSong'. On button pressed I wish to execute two functions which are '_pageManager.addSong' and 'addSongToQueue'.
This is the code
ValueListenableBuilder<bool>(
valueListenable: _pageManager.isLastSongNotifier,
builder: (_, isLast, __) {
return IconButton(
icon: Icon(Icons.skip_next),
onPressed: (isLast)
? _pageManager.addSong
: _pageManager.onNextSongButtonPressed;
);
}),
I see your logic
I might suggest to create a function
void onAddSong() {
_pageManager.addSong();
// addSongToQueue()
}
Then call this
onPressed: (isLast)
? this.onAddSong
: _pageManager.onNextSongButtonPressed;
);
I'd suggest you to think in the scalability of this widget with that isLast #param, is it ok?
Don't use a ternary, and instead just use a function body.
onPressed: () {
function1();
function2();
}
You can use if in the oppressed function like this
onPressed: (){
if(isLast){
_pageManager.addSong
}else{
_pageManager.onNextSongButtonPressed;
}
}
or use it like this if you have to check only one condition
onPressed: () =>
isLast ? _pageManager.addSong
:
_pageManager.onNextSongButtonPressed;
I have following problem. I want to create an if else statement where if the condition is true you get redirected to a certain page & if it is false to another. For that I need to check whether a list has more than one object, but I don't know how to formulate the condition.
Here is the if else statement (I wrote 3>0 for the condition as a placeholder)
child: ListView.builder(
itemCount: modell.modelData.length,
itemBuilder: (context, index) => GestureDetector(
onTap: () {
if (3 > 0) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Modelljahre(
modelData: this.modell.modelData[index],
modell: modell,
)));
} else {
Navigator.push(context,
MaterialPageRoute(builder: (context) => Treibstoff()));
}
;
},
and here a part of the dataset (so I want to check whether the VariantMakeData list of each car Modell contains more than one object, how can I do that?
ModelMakeData(id: 27, title: "Touareg", variantenData: <VariantMakeData>[
VariantMakeData(
id: 1,
bigtitle: "1. Generation",
title: "Modelljahre 2002-2010",
),
VariantMakeData(
id: 2,
bigtitle: "2. Generation",
title: "Modelljahre 2010-2018",
),
Use:
if (modell.modelData[index].variantenData.length >1)
Because you want to check the length of variantenData at this current index
You can use the propriety isNotEmpty like this:
if (modell.modelData.isNotEmpty){
//Your code
} else {
// Your code
}
I have the following flow Screen 1 -> Screen 2 -> Dialog (in a separate widget).
Screen 2 displays a dialog (Close? Yes or No). If someone presses Yes, I would like to return to the Screen 1, if they press No, just close the dialog and return to Screen 2. What I currently do is when Yes is tapped, I do Navigator.pop(context) twice. Is this a good practice? Is there a way to pass the context of Screen 2 to my dialog widget so I can pop that one directly?
Personally, I think it would be better to pass the response from the dialog back to the page, and let the page handle the rest.
You can do this:
//I'm using a raised button just to call the alert as an example...
RaisedButton(
child: Text('Press me'),
//This part here is the important part
onPressed: () async {
//You can return anything when you use Navigator.pop
//In this case I'm returning a bool indicating if the page should close or not.
//You have to await this because it depends on user input.
bool shouldPopResult = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
//The content of your dialog
actions: <Widget>[
// The value you pass here in Navigator.of(context).pop
// is the value that will be stored in shouldPopResult,
// so if "Yes" is pressed, true will return...
// and if "No", false is returned.
FlatButton(
child: Text('Yes'),
onPressed: () => Navigator.of(context).pop(true),
),
FlatButton(
child: Text('No'),
onPressed: () => Navigator.of(context).pop(false),
)
],
),
);
// This is for if the user dismisses the dialog without pressing a button
// In that case shouldPopResult would be null, so I'm setting it to false.
// You can prevent the user from dismissing the dialog
// setting barrierDismissible to false in the showDialog method.
if (shouldPopResult == null) shouldPopResult = false;
// And finally with the dialog already dismissed, you can decide
// to go back or not.
if (shouldPopResult) Navigator.of(context).pop();
});
As usual you can extract the dialog as a Widget, or extract the function that handles the dialog response altogether or anything else.
You can see the example of returning data from a page in the flutter documentation here.
hello there i have this classes
ServicesIndex
ServicesCreate
ServicesEdit
what i want to do is on click of button in either Create or Edit i want to pop all alerts and pages and push replacement to ServicesIndex
what should i do exactly ?
the button which will be clicked in Services Create and Edit
showSuccessMessage(context) {
var responsivenessController = ResponsivenessController(context);
Alert(
context: context,
type: AlertType.success,
style: AlertStyle(titleStyle: Theme
.of(context)
.textTheme
.bodyText1
, descStyle: Theme
.of(context)
.textTheme
.bodyText1),
title: translator.currentLanguage == 'ar' ? 'تم الحفظ'
: 'Stored Successfully',
desc: translator.currentLanguage == 'ar' ? 'تمت عملية الحفظ بنجاح'
: 'Information Stored Successfully',
buttons: [
DialogButton(
child: Text(
translator.currentLanguage == 'ar' ?
"المتابعة"
: 'OK',
style: TextStyle(color: Colors.white,
fontSize: responsivenessController.bodyFont),
),
onPressed: () {
Navigator.pop(context);
}
)
],
).show();
}
its all in on pressed event what code do you suggest ?
about the stack of elements its
Index
---Create
---SuccessMessage
---Edit
---SuccessMessage
so the action should pop 2 times and push replacement
i can of course hard code like this
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
Navigator.pop(context);
Navigator.pushReplacement(context, MaterialPageRoute(
builder: (BuildContext context) => className
));
}
but i want something more flexible like just pass the Class name and it will return to it while popping everything before it
Note : Named Routes will not work because every page requires some parameters that will be passed later in the process i can't fetch them all in main.dart i will cause slow performance
If you know how many pop you need to call then simply use popUntil with a counter.
Code
// In this case we want to pop 4 times
void onPressed() {
int count = 0;
Navigator.popUntil(context, (route) => count++ == 4);
}