How can set a parameter only if a variable is not null. Is there a null aware operator or technique for this?
Eg:
this.startWidget = FormBuilderDateTimePicker(
key: UniqueKey(),
controller: _startController,
enabled: true,
// onChanged: _onChanged,
inputType: InputType.time,
decoration: InputDecoration(
labelText: 'Start Time',
),
initialTime: TimeOfDay(hour: 8, minute: 0),
initialValue: StartinitialValue,
enabled: true,
);
Here, I want initialValue: StartinitialValue only if StartinitialValue is not null.
I dont want to do the following:
if (StartinitialValue == null) {
this.startWidget = FormBuilderDateTimePicker(
key: UniqueKey(),
controller: _startController,
enabled: true,
// onChanged: _onChanged,
inputType: InputType.time,
decoration: InputDecoration(
labelText: 'Start Time',
),
initialTime: TimeOfDay(hour: 8, minute: 0),
enabled: true,
);
} else {
this.startWidget = FormBuilderDateTimePicker(
key: UniqueKey(),
controller: _startController,
enabled: true,
// onChanged: _onChanged,
inputType: InputType.time,
decoration: InputDecoration(
labelText: 'Start Time',
),
initialTime: TimeOfDay(hour: 8, minute: 0),
initialValue: StartinitialValue,
enabled: true,
);
}
What is the proper way to do what I need?
A parameter can be either nullable or non-nullable in Dart. I think here what you need is using optional parameter which will set your initial value.
https://zaiste.net/posts/dart-optional-function-parameters/
example code:
class MyClass {
final TimeOfDay startinitialValue;
MyClass(startinitialValue = const TimeOfDay(hour: 8, minute: 0))
}
No. The only way not to pass an argument in a function call is to have no argument in the call. You can't have an argument expression which is ignored if it's null.
The one thing you can do is to figure out what the function you call will do if you omit the argument, and then pass the same value yourself ... if that is possible (it might not be, if the function uses a default value that you cannot create from outside the same library).
In this case you are in luck. Looking at the constructor, not passing the optional initialValue is exactly the same as passing null as a value. (It's an optional nullable parameter with no default value, which means it has a "default default-value" of null).
So, just pass initiaValue: StartinitialValue even when StartinitialValue is null. It works exactly the same as not passing the parameter when the value is null.
Related
I have these classes
class CustomPopupAction<T> extends CustomAction {
final Icon icon;
final List<CustomPopupActionItem<T>> actions;
final void Function(T) onActionSelected;
CustomPopupAction({
required this.icon,
required this.actions,
required this.onActionSelected,
});
}
class CustomPopupActionItem<T> {
final T value;
final Widget Function(T) itemBuilder;
CustomPopupActionItem({
required this.value,
required this.itemBuilder,
});
}
and I am trying to create overflow menu which will work like this:
if the button is visible, I will create PopupMenuButton
if the button is overflown, I will create ListTile which will open dialog
it can hold multiple different types like CustomAction, CustomPopupAction<Locale>, CustomPopupAction<String>...
I am building that row like this
if (a is CustomPopupAction) {
return PopupMenuButton(
icon: a.icon,
onSelected: (i) => a.onActionSelected(i),
itemBuilder: (context) {
return a.actions.map((i) => PopupMenuItem(
value: i.value,
child: i.itemBuilder(i.value),
)).toList();
},
);
} else {
return IconButton(...);
}
and finally my main code:
...
return OverflowMenu(
actions: [
CustomPopupAction<Locale>(
icon: Icon(Icons.translate),
actions: [
CustomPopupActionItem<Locale>(
value: Locale('en'),
itemBuilder: (l) => ListTile(title: Text(l.toString()),
),
],
onActionSelected: (l) => print(l),
],
);
But this doesn't work for me, I am getting an exception Expected a value of type '(dynamic) => Widget', but got one of type '(Locale) => ListTile'.
I know it's because if (a is CustomPopupAction) is actually getting CustomPopupAction<dynamic>.
can I somehow convince Dart that a nas not dynamic type and that it should work with it's real type?
if not, why am I getting that exception? Locale can be assigned to dynamic variable and ListTile is clearly a Widget.
can I do this without going through dynamics at all?
I created a login page and I need to add these things to my password. How do I do it with validation alert message?
Minimum 1 Upper case
Minimum 1 lowercase
Minimum 1 Numeric Number
Minimum 1 Special Character
Common Allow Character ( ! # # $ & * ~ )
Your regular expression should look like:
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$
Here is an explanation:
r'^
(?=.*[A-Z]) // should contain at least one upper case
(?=.*[a-z]) // should contain at least one lower case
(?=.*?[0-9]) // should contain at least one digit
(?=.*?[!##\$&*~]) // should contain at least one Special character
.{8,} // Must be at least 8 characters in length
$
Match above expression with your password string. Using this method-
String? validatePassword(String value) {
RegExp regex =
RegExp(r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$');
if (value.isEmpty) {
return 'Please enter password';
} else {
if (!regex.hasMatch(value)) {
return 'Enter valid password';
} else {
return null;
}
}
}
You need to use Regular Expression to validate the structure.
bool validateStructure(String value){
String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$';
RegExp regExp = new RegExp(pattern);
return regExp.hasMatch(value);
}
output:
Vignesh123! : true
vignesh123 : false
VIGNESH123! : false
vignesh# : false
12345678? : false
This function will validate the passed value is having the structure or not.
var _usernameController = TextEditingController();
String _usernameError;
...
#override
Widget build(BuildContext context) {
return
...
TextFormField(
controller: _usernameController,
decoration: InputDecoration(
hintText: "Username", errorText: _usernameError),
style: TextStyle(fontSize: 18.0),
),
Container(
width: double.infinity,
height: 50.0,
child: RaisedButton(
onPressed: validate,
child: Text(
"Login",
style: TextStyle(color: Colors.white),
),
color: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
),
),
),
...
}
...
validate(){
if(!validateStructure(_usernameController.text)){
setState(() {
_usernameError = emailError;
_passwordError = passwordError;
});
// show dialog/snackbar to get user attention.
return;
}
// Continue
}
You have to use TextFormField widget with validator property.
TextFormField(
validator: (value) {
// add your custom validation here.
if (value.isEmpty) {
return 'Please enter some text';
}
if (value.length < 3) {
return 'Must be more than 2 charater';
}
},
),
Take a look on official docs: https://flutter.dev/docs/cookbook/forms/validation
You can achieve this using below flutter plugin.
wc_form_validators
You can use it something like this:
TextFormField(
decoration: InputDecoration(
labelText: 'Password',
),
validator: Validators.compose([
Validators.required('Password is required'),
Validators.patternString(r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$', 'Invalid Password')
]),
),
Its documentation is really good. You can read it for more util functions like this.
By using extension in dart
extension PasswordValidator on String {
bool isValidPassword() {
return RegExp(
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$')
.hasMatch(this);
}
}
You can apply this in your textfield like
TextFormField(
autovalidate: true,
validator: (input) => input. isValidPassword() ? null : "Check your password...",
)
here is the complete answer
Write a Dart program to check whether a string is a valid password. a. A password must have at least ten characters. b. A password
consists of only letters and digits. c. A password must contain at
least two digits.
import 'dart:io';
main() {
var password;
stdout.write("Enter You'r Password: ");
password=stdin.readLineSync();
if(password.length>=10 && !password.contains(RegExp(r'\W')) && RegExp(r'\d+\w*\d+').hasMatch(password))
{
print(" \n\t$password is Valid Password");
}
else
{
print("\n\t$password is Invalid Password");
}
Flutter Login Validation
///creating Username and Password Controller.
TextEditingController username=TextEditingController();
TextEditingController password=TextEditingController();
Form(
child: Builder(
builder: (context) {
return Column(
children: [
TextFormField(
controller: username,
validator: (CurrentValue){
var nonNullValue=CurrentValue??'';
if(nonNullValue.isEmpty){
return ("username is required");
}
if(!nonNullValue.contains("#")){
return ("username should contains #");
}
return null;
},
),
TextFormField(
controller: password,
validator: (PassCurrentValue){
RegExp regex=RegExp(r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$');
var passNonNullValue=PassCurrentValue??"";
if(passNonNullValue.isEmpty){
return ("Password is required");
}
else if(passNonNullValue.length<6){
return ("Password Must be more than 5 characters");
}
else if(!regex.hasMatch(passNonNullValue)){
return ("Password should contain upper,lower,digit and Special character ");
}
return null;
},
),
ElevatedButton(onPressed: (){
if(Form.of(context)?.validate()?? false){
Navigator.of(context).push(MaterialPageRoute(builder: (_)=>loginpage()));
}
}, child: Text("Login"))
],
);
}
),
)
in this picture you can see when you Enter inValid username and password it will not Navigate to another page.
when you Enter Valid Username and Password it will Navigate to another Page.
this is the best regx
bool passValid = RegExp("^(?=.{8,32}\$)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!##\$%^&*(),.?:{}|<>]).*").hasMatch(value);
if (value.isEmpty ||!passValid)
{
return 'error';
}
I need to create DropdownButton widget with int items, but it does not work as expected.
This is the code:
DropdownButton<int>(
hint: Text("Pick"),
items: <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((int value) {
return new DropdownMenuItem<int>(
value: _number_tickets_total,
child: new Text(_number_tickets_total.toString()),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_number_tickets_total = newVal;
});
})
The problem is that the widget never gets the value selected. I always see the "hint" text even when I choose a value.
What you are missing is value attribute of the DropdownButton. When that value is null, it will show the hint, otherwise latest selected value.
The values that you are using in the drop-down item is irrelevant from the whole list, that's why you should just pass them the related information. I modified your code with the value attribute below.
DropdownButton<int>(
hint: Text("Pick"),
value: _number_tickets_total,
items: <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((int value) {
return new DropdownMenuItem<int>(
value: value,
child: new Text(value.toString()),
);
}).toList(),
onChanged: (newVal) {
setState(() {
_number_tickets_total = newVal;
});
});
I'm trying to implement same layout in flutter how can i achieve it, i have already tried using wrap widget but Textfield getting full width and changing textfield width dynamically based on content is not possible
I don't know if this is too late. But this library is exactly what you need. You have all steps on the website.
It's a library called Flutter Chips. There are the steps and I'll put the link from the library too.
https://pub.dev/packages/flutter_chips_input
First of all install the library:
dependencies:
flutter_chips_input: ^1.9.4
Here is the code part:
ChipsInput(
initialValue: [
AppProfile('John Doe', 'jdoe#flutter.io', 'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg')
],
decoration: InputDecoration(
labelText: "Select People",
),
maxChips: 3,
findSuggestions: (String query) {
if (query.length != 0) {
var lowercaseQuery = query.toLowerCase();
return mockResults.where((profile) {
return profile.name.toLowerCase().contains(query.toLowerCase()) || profile.email.toLowerCase().contains(query.toLowerCase());
}).toList(growable: false)
..sort((a, b) => a.name
.toLowerCase()
.indexOf(lowercaseQuery)
.compareTo(b.name.toLowerCase().indexOf(lowercaseQuery)));
} else {
return const <AppProfile>[];
}
},
onChanged: (data) {
print(data);
},
chipBuilder: (context, state, profile) {
return InputChip(
key: ObjectKey(profile),
label: Text(profile.name),
avatar: CircleAvatar(
backgroundImage: NetworkImage(profile.imageUrl),
),
onDeleted: () => state.deleteChip(profile),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
);
},
suggestionBuilder: (context, state, profile) {
return ListTile(
key: ObjectKey(profile),
leading: CircleAvatar(
backgroundImage: NetworkImage(profile.imageUrl),
),
title: Text(profile.name),
subtitle: Text(profile.email),
onTap: () => state.selectSuggestion(profile),
);
},
)
I'm familiar with form validation using a TextFormField in Flutter, but is it possible to integrate a DropdownButton into a Form and require one of its value be selected before submission?
Basically, integrate DropdownButton validation into this basic Flutter validation example:
https://flutter.io/cookbook/forms/validation/
Dart Package have already the widget DropdownButtonFormField for this. Here is an example of how to use it:
List<String> typeNeg = [
"One",
"Two",
"Three",];
String dropdownValue = "One";
DropdownButtonFormField<String>(
value: dropdownValue,
hint: Text("Type of business"),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
validator: (String value) {
if (value?.isEmpty ?? true) {
return 'Please enter a valid type of business';
}
},
items: typeNeg
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onSaved: (val) => setState(() => _user.typeNeg = val),
),
The user model is as follows:
class User {
int id;
String name;
String email;
String typeNeg;
User({this.id, this.name, this.email, this.typeNeg});
factory User.fromJson(Map<String, dynamic> parsedJson) {
return User(
id: parsedJson["id"],
name: parsedJson["name"] as String,
email: parsedJson["email"] as String,
typeNeg: parsedJson["typeNeg"] as String,
);
}
save(){
print("User saved");
}
}
To try the validator option change String dropdownValue = "One"; to String dropdownValue = null;
From text_form_field.dart file in Flutter's source code you can see that TextFormField is no more than a FormField emitting a TextField widget in its builder callback. You can write your own DropdownFormField using a similar pattern. Here's mine:
import 'package:flutter/material.dart';
class DropdownFormField<T> extends FormField<T> {
DropdownFormField({
Key key,
InputDecoration decoration,
T initialValue,
List<DropdownMenuItem<T>> items,
bool autovalidate = false,
FormFieldSetter<T> onSaved,
FormFieldValidator<T> validator,
}) : super(
key: key,
onSaved: onSaved,
validator: validator,
autovalidate: autovalidate,
initialValue: items.contains(initialValue) ? initialValue : null,
builder: (FormFieldState<T> field) {
final InputDecoration effectiveDecoration = (decoration ?? const InputDecoration())
.applyDefaults(Theme.of(field.context).inputDecorationTheme);
return InputDecorator(
decoration:
effectiveDecoration.copyWith(errorText: field.hasError ? field.errorText : null),
isEmpty: field.value == '' || field.value == null,
child: DropdownButtonHideUnderline(
child: DropdownButton<T>(
value: field.value,
isDense: true,
onChanged: field.didChange,
items: items.toList(),
),
),
);
},
);
}
The key is to bind DropdownButton's onChanged to field.didChange. Usage is pretty straightforward:
DropdownFormField<String>(
validator: (value) {
if (value == null) {
return 'Required';
}
},
onSaved: (value) {
// ...
},
decoration: InputDecoration(
border: UnderlineInputBorder(),
filled: true,
labelText: 'Demo',
),
initialValue: null,
items: [
DropdownMenuItem<String>(
value: '1',
child: Text('1'),
),
DropdownMenuItem<String>(
value: '2',
child: Text('2'),
)
],
),
I got the idea from this site. The difference is that my version of DropdownFormField is closer to Flutter's native implementation (which extends TextFormField instead of wrapping it inside a StatefulWidget).