Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1a6372f
Add phone validator
martijn00 May 24, 2024
6ddcac4
Add creditcard validators
martijn00 May 24, 2024
b23b9ed
Format
martijn00 May 24, 2024
a72c313
Add color code check
martijn00 May 24, 2024
f8f76b7
Format
martijn00 May 24, 2024
6976dbf
Add more
martijn00 May 24, 2024
b6c188e
add notMatch to FormFieldValidator; scenario: require password not to…
falconwoods Aug 7, 2023
2e2394c
Add readme for not match
martijn00 May 24, 2024
3813c27
Update changelog
martijn00 May 24, 2024
1171dbc
Format
martijn00 May 24, 2024
fa61a91
Update changelog
martijn00 May 24, 2024
ea3c57b
Merge branch 'notmatch-pr' into validators
martijn00 May 24, 2024
7b556b8
Add fileSize
martijn00 May 24, 2024
d1898d0
Add more
martijn00 May 24, 2024
ce8dbaa
More
martijn00 May 24, 2024
4f3a54a
Add tests
martijn00 May 24, 2024
608fa12
Fix tests
martijn00 May 24, 2024
5f7c10c
Add password
martijn00 May 24, 2024
e8102f5
Revert to dateString
martijn00 May 25, 2024
4829585
Update README.md
martijn00 May 25, 2024
f99a0be
Add checks
martijn00 May 25, 2024
5cc6aa4
Add assert
martijn00 May 25, 2024
5698e39
Color check
martijn00 May 25, 2024
cbf450c
Update version
martijn00 May 25, 2024
564c2f4
Clean test
martijn00 May 25, 2024
6f493e1
Using string for files
martijn00 May 25, 2024
410698f
Check credit card
martijn00 May 25, 2024
a3efb01
Update test
martijn00 May 25, 2024
e19d17d
Fix date range
martijn00 May 26, 2024
c7274d4
Add cc check test
martijn00 May 26, 2024
1a36a44
More tests
martijn00 May 26, 2024
862cb5c
Improve bytes
martijn00 May 26, 2024
927a761
Update changelog
martijn00 May 26, 2024
77b67de
More
martijn00 May 26, 2024
3536f88
Format
martijn00 May 26, 2024
2e7070f
Add or
martijn00 May 26, 2024
42ca441
Add extensions
martijn00 May 26, 2024
ec00125
Format
martijn00 May 26, 2024
7ca36a0
Translations
martijn00 May 26, 2024
d501e65
Add case
martijn00 May 26, 2024
2bd2e8b
Merge
martijn00 May 26, 2024
d69546e
Fix
martijn00 May 26, 2024
54b24b5
Add more phone tests
martijn00 May 26, 2024
925ade1
Format
martijn00 May 26, 2024
5ce3ef1
Fix test
martijn00 May 26, 2024
e8b7d34
Add more to example
martijn00 May 26, 2024
bc3523f
Add some
martijn00 May 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
## 10.0.2
* Reland generated l10n files
## 10.1.0

* Add creditCardExpirationDate
* Add creditCardExpirationDateNotExpired
* Add creditCardCVC
* Add colorCode
* Add phoneNumber
* Add uppercase
* Add lowercase
* Add file extension
* Add max file size
* Add notMatch
* Add range
* Add date range
* Add must be true
* Add must be false
* Add special characters
* Add numeric characters
* Add lowercase characters
* Add uppercase characters
* Add password
* Re-land generated l10n files
* Add Bulgarian

## 10.0.1
Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,18 @@ URL, min, max, minLength, maxLength, minWordsCount, maxWordsCount, IP, credit ca
Available built-in validators include:

- `FormBuilderValidators.creditCard()` - requires the field's value to be a valid credit card number.
- `FormBuilderValidators.creditCardExpirationDate()` - requires the field's value to be a valid credit card expiration date.
- `FormBuilderValidators.creditCardExpirationDateNotExpired()` - requires the field's value to be aa valid credit card expiration date and not be expired.
- `FormBuilderValidators.creditCardCVC()` - requires the field's value to be a valid credit card CVC number.
- `FormBuilderValidators.colorCode()` - requires the field's value to be a valid color code.
- `FormBuilderValidators.date()` - requires the field's value to be a valid date string.
- `FormBuilderValidators.dateRange()` - requires the field's value to be a within a date range.
- `FormBuilderValidators.email()` - requires the field's value to be a valid email address.
- `FormBuilderValidators.equal()` - requires the field's value to be equal to the provided object.
- `FormBuilderValidators.integer()` - requires the field's value to be an integer.
- `FormBuilderValidators.ip()` - requires the field's value to be a valid IP address.
- `FormBuilderValidators.match()` - requires the field's value to match the provided regex pattern.
- `FormBuilderValidators.notMatch()` - requires the field's value to not match the provided regex pattern.
- `FormBuilderValidators.max()` - requires the field's value to be less than or equal to the provided number.
- `FormBuilderValidators.maxLength()` - requires the length of the field's value to be less than or equal to the provided maximum size.
- `FormBuilderValidators.maxWordsCount()` - requires the word count of the field's value to be less than or equal to the provided maximum count.
Expand All @@ -65,6 +71,18 @@ Available built-in validators include:
- `FormBuilderValidators.numeric()` - requires the field's value to be a valid number.
- `FormBuilderValidators.required()` - requires the field to have a non-empty value.
- `FormBuilderValidators.url()` - requires the field's value to be a valid URL.
- `FormBuilderValidators.uppercase()` - requires the field's value to be uppercase.
- `FormBuilderValidators.lowercase()` - requires the field's value to be lowercase.
- `FormBuilderValidators.fileExtension()` - requires the field's value to a valid file extension.
- `FormBuilderValidators.fileSize()` - requires the field's to be less than the max size.
- `FormBuilderValidators.mustBeTrue()` - requires the field's to be true.
- `FormBuilderValidators.mustBeFalse()` - requires the field's to be false.
- `FormBuilderValidators.hasSpecialChars()` - requires the field's to contain a specified number of special characters.
- `FormBuilderValidators.hasUppercaseChars()` - requires the field's to contain a specified number of uppercase characters.
- `FormBuilderValidators.hasLowercaseChars()` - requires the field's to contain a specified number of lowercase characters.
- `FormBuilderValidators.hasNumericChars()` - requires the field's to contain a specified number of numeric characters.
- `FormBuilderValidators.conditional()` - requires the field's to validate with another validator conditionally.
- `FormBuilderValidators.password()` - requires the field's to be a valid password that matched required conditions.

### Supported languages

Expand Down
18 changes: 17 additions & 1 deletion lib/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,21 @@
"notEqualErrorText": "This field value must not be equal to {value}.",
"numericErrorText": "Value must be numeric.",
"requiredErrorText": "This field cannot be empty.",
"urlErrorText": "This field requires a valid URL address."
"urlErrorText": "This field requires a valid URL address.",
"phoneErrorText": "This field requires a valid phone number.",
"creditCardExpirationDateErrorText": "This field requires a valid expiration date.",
"creditCardExpiredErrorText": "This credit card has expired.",
"creditCardCVCErrorText": "This field requires a valid CVC code.",
"colorCodeErrorText": "Value should be a valid {colorCode} color code.",
"uppercaseErrorText": "Value must be uppercase.",
"lowercaseErrorText": "Value must be lowercase.",
"fileExtensionErrorText": "File extension must be {extensions}",
"fileSizeErrorText": "File size must be less than {maxSize} while it is {fileSize}",
"dateRangeErrorText": "Date must be in range {min} - {max}",
"mustBeTrueErrorText": "This field must be true.",
"mustBeFalseErrorText": "This field must be false.",
"containsSpecialCharErrorText": "Value must contain at least {min} special characters.",
"containsUppercaseCharErrorText": "Value must contain at least {min} uppercase characters.",
"containsLowercaseCharErrorText": "Value must contain at least {min} lowercase characters.",
"containsNumberErrorText": "Value must contain at least {min} numbers."
}
282 changes: 282 additions & 0 deletions lib/src/form_builder_validators.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import 'dart:io';

import 'package:flutter/material.dart';
import '../form_builder_validators.dart';

import 'utils/helpers.dart';
import 'utils/validators.dart';

/// For creation of [FormFieldValidator]s.
Expand Down Expand Up @@ -267,6 +270,16 @@ class FormBuilderValidators {
? errorText ?? FormBuilderLocalizations.current.matchErrorText
: null;

/// [FormFieldValidator] that requires the field's value not to match the provided regex pattern.
static FormFieldValidator<String> notMatch(
String pattern, {
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
RegExp(pattern).hasMatch(valueCandidate!)
? errorText ?? FormBuilderLocalizations.current.matchErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a valid number.
static FormFieldValidator<String> numeric({
String? errorText,
Expand Down Expand Up @@ -295,6 +308,42 @@ class FormBuilderValidators {
? errorText ?? FormBuilderLocalizations.current.creditCardErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a valid credit card expiration date.
static FormFieldValidator<String> creditCardExpirationDate({
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
!isCreditCardExpirationDate(valueCandidate!)
? errorText ??
FormBuilderLocalizations.current.creditCardExpirationDateErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a valid credit card expiration date and not expired.
static FormFieldValidator<String> creditCardExpirationDateNotExpired({
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
!isCreditCardExpirationDate(valueCandidate!) ||
!isNotExpiredCreditCardDate(valueCandidate!)
? errorText ??
FormBuilderLocalizations.current.creditCardExpiredErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a valid credit card CVC.
static FormFieldValidator<String> creditCardCVC({
String? errorText,
}) =>
compose<String>(
[
minLength(3,
errorText: errorText ??
FormBuilderLocalizations.current.creditCardCVCErrorText),
maxLength(4,
errorText: errorText ??
FormBuilderLocalizations.current.creditCardCVCErrorText),
],
);

/// [FormFieldValidator] that requires the field's value to be a valid IP address.
/// * [version] is a `String` or an `int`.
static FormFieldValidator<String> ip({
Expand All @@ -314,4 +363,237 @@ class FormBuilderValidators {
!isDate(valueCandidate!)
? errorText ?? FormBuilderLocalizations.current.dateStringErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a date within a certain range.
static FormFieldValidator<String> dateRange({
required String minDate,
required String maxDate,
String? errorText,
}) {
return compose<String>(
[
minDate.isNotEmpty
? dateString(errorText: errorText)
: (valueCandidate) => null,
maxDate.isNotEmpty
? dateString(errorText: errorText)
: (valueCandidate) => null,
(valueCandidate) {
if (valueCandidate == null || valueCandidate.isEmpty) {
return null;
}

final minDateTime = DateTime.tryParse(minDate);
final maxDateTime = DateTime.tryParse(maxDate);
final valueDateTime = DateTime.tryParse(valueCandidate);

if (minDateTime != null &&
valueDateTime!.isBefore(minDateTime) &&
maxDateTime != null &&
valueDateTime.isAfter(maxDateTime)) {
return errorText ??
FormBuilderLocalizations.current.dateRangeErrorText(
minDate,
maxDate,
);
}

return null;
},
],
);
}

/// [FormFieldValidator] that requires the field's value to be a valid phone number.
static FormFieldValidator<String> phoneNumber({
String? errorText,
}) =>
(valueCandidate) =>
true == valueCandidate?.isNotEmpty && !isPhoneNumber(valueCandidate!)
? errorText ?? FormBuilderLocalizations.current.phoneErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a valid color code.
/// * [formats] is a list of allowed color code formats (e.g., ['hex', 'rgb', 'hsl'])
static FormFieldValidator<String> colorCode({
List<String> formats = const ['hex', 'rgb', 'hsl'],
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
!isColorCode(valueCandidate!, formats: formats)
? errorText ??
FormBuilderLocalizations.current
.colorCodeErrorText(formats.join(', '))
: null;

/// [FormFieldValidator] that requires the field's value to be uppercase.
static FormFieldValidator<String> uppercase({
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
valueCandidate!.toUpperCase() != valueCandidate
? errorText ?? FormBuilderLocalizations.current.uppercaseErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be lowercase.
static FormFieldValidator<String> lowercase({
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
valueCandidate!.toLowerCase() != valueCandidate
? errorText ?? FormBuilderLocalizations.current.lowercaseErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a valid file extension.
static FormFieldValidator<File> fileExtension({
required List<String> allowedExtensions,
String? errorText,
}) =>
(File? valueCandidate) => valueCandidate == null
? null
: !allowedExtensions.contains(
fileExtensionFromPath(valueCandidate.path).toLowerCase())
? errorText ??
FormBuilderLocalizations.current
.fileExtensionErrorText(allowedExtensions.join(', '))
: null;

/// [FormFieldValidator] that restricts the size of an file to be less than or equal to the provided maximum size.
/// * [maxSize] is the maximum size in bytes.
static FormFieldValidator<File> fileSize({
required int maxSize,
String? errorText,
}) =>
(File? valueCandidate) => valueCandidate == null
? null
: valueCandidate.existsSync() && valueCandidate.lengthSync() > maxSize
? errorText ??
FormBuilderLocalizations.current.fileSizeErrorText(
formatBytes(valueCandidate.lengthSync()),
formatBytes(maxSize),
)
: null;

/// [FormFieldValidator] that applies another validator conditionally.
static FormFieldValidator<T> conditional<T>(
bool Function(T value) condition,
FormFieldValidator<T> validator,
) =>
(T? valueCandidate) =>
condition(valueCandidate as T) ? validator(valueCandidate) : null;

/// [FormFieldValidator] that requires the field's value to be within a certain range.
static FormFieldValidator<T> range<T>(
num minValue,
num maxValue, {
bool inclusive = true,
String? errorText,
}) {
return compose<T>(
[
min(minValue, inclusive: inclusive, errorText: errorText),
max(maxValue, inclusive: inclusive, errorText: errorText),
],
);
}

/// [FormFieldValidator] that requires the field's value to be a bool and true.
static FormFieldValidator<bool> mustBeTrue({
String? errorText,
}) =>
(valueCandidate) => valueCandidate != true
? errorText ?? FormBuilderLocalizations.current.mustBeTrueErrorText
: null;

/// [FormFieldValidator] that requires the field's value to be a bool and false.
static FormFieldValidator<bool> mustBeFalse({
String? errorText,
}) =>
(valueCandidate) => valueCandidate != false
? errorText ?? FormBuilderLocalizations.current.mustBeFalseErrorText
: null;

/// [FormFieldValidator] that requires the field's value to contain an amount of special characters.
static FormFieldValidator<String> hasSpecialChars({
int atLeast = 1,
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
specialCharLength(valueCandidate!) >= atLeast
? null
: errorText ??
FormBuilderLocalizations.current
.containsSpecialCharErrorText(atLeast);

/// [FormFieldValidator] that requires the field's value to contain an amount of uppercase characters.
static FormFieldValidator<String> hasUppercaseChars({
int atLeast = 1,
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
uppercaseCharLength(valueCandidate!) >= atLeast
? null
: errorText ??
FormBuilderLocalizations.current
.containsUppercaseCharErrorText(atLeast);

/// [FormFieldValidator] that requires the field's value to contain an amount of lowercase characters.
static FormFieldValidator<String> hasLowercaseChars({
int atLeast = 1,
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
lowercaseCharLength(valueCandidate!) >= atLeast
? null
: errorText ??
FormBuilderLocalizations.current
.containsLowercaseCharErrorText(atLeast);

/// [FormFieldValidator] that requires the field's value to contain an amount of numeric characters.
static FormFieldValidator<String> hasNumericChars({
int atLeast = 1,
String? errorText,
}) =>
(valueCandidate) => true == valueCandidate?.isNotEmpty &&
numberCharLength(valueCandidate!) >= atLeast
? null
: errorText ??
FormBuilderLocalizations.current.containsNumberErrorText(atLeast);

/// [FormFieldValidator] that requires the field's value to be a valid password.
/// * [minLength] is the minimum length of the password. By default `8`
/// * [maxLength] is the maximum length of the password. By default `32`
/// * [uppercase] is the minimum amount of uppercase characters. By default `1`
/// * [lowercase] is the minimum amount of lowercase characters. By default `1`
/// * [number] is the minimum amount of numeric characters. By default `1`
/// * [specialChar] is the minimum amount of special characters. By default `1`
/// * [errorText] is the error message to display when the password is invalid
static FormFieldValidator<String> password({
int minLength = 8,
int maxLength = 32,
int uppercase = 1,
int lowercase = 1,
int number = 1,
int specialChar = 1,
String? errorText,
}) {
return FormBuilderValidators.compose<String>(
[
FormBuilderValidators.minLength(minLength, errorText: errorText),
FormBuilderValidators.maxLength(maxLength, errorText: errorText),
if (uppercase > 0)
FormBuilderValidators.hasUppercaseChars(
atLeast: uppercase, errorText: errorText),
if (lowercase > 0)
FormBuilderValidators.hasLowercaseChars(
atLeast: lowercase, errorText: errorText),
if (number > 0)
FormBuilderValidators.hasNumericChars(
atLeast: number, errorText: errorText),
if (specialChar > 0)
FormBuilderValidators.hasSpecialChars(
atLeast: specialChar, errorText: errorText),
],
);
}
}
Loading