Skip to content

Commit ee762d7

Browse files
update readme
1 parent 484e639 commit ee762d7

File tree

1 file changed

+80
-8
lines changed

1 file changed

+80
-8
lines changed

README-updated.md

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,16 @@ URL, min, max, minLength, maxLength, minWordsCount, maxWordsCount, IP, credit ca
7373
Generally, the validators are separated in three main groups:
7474
1. Required validators: makes a field optional or required.
7575
2. Type validators: checks the type of the field.
76-
3. Other validators: makes other types of checking.
76+
3. Other validators: make any other kind of check that is not related to null or type validation.
7777

7878
Generally, we build a validator composing those three types in the following way:
7979
<requiredValidator>(<typeValidator>(<otherValidator>()))
8080

81+
For example:
82+
- Make the field required, check if it is of type `num` or a `String` parsable to one and then check if
83+
it is greater than 10.
84+
`Validators.required(Validators.num(Validators.greaterThan(10)))`
85+
8186

8287

8388
### Collection validators
@@ -330,7 +335,6 @@ On validation, each validator is run, and if any validator returns a non-null va
330335

331336
Example:
332337

333-
TODO update this example (checkpoint)
334338
```Dart
335339
TextFormField(
336340
decoration: InputDecoration(labelText: 'Age'),
@@ -362,6 +366,11 @@ see [override_form_builder_localizations_en](example/lib/override_form_builder_l
362366

363367
## Migrations
364368

369+
### v11 to v12
370+
- Deprecate `FormBuilderValidators` class with its static methods as validators.
371+
- Instead, you should use `Validators` class.
372+
TODO implement the remaining of breaking changes
373+
365374
### v10 to v11
366375

367376
- All validators now first check for null or empty value and return an error if so. You can set `checkNullOrEmpty` to `false` if you want to avoid this behavior.
@@ -373,7 +382,7 @@ see [override_form_builder_localizations_en](example/lib/override_form_builder_l
373382
Remove `context` as a parameter to validator functions. For example, `FormBuilderValidators.required(context)` becomes `FormBuilderValidators.required()` without `context` passed in.
374383

375384
## How this package works
376-
This package comes with several most common `FormFieldValidator`s such as required, numeric, mail,
385+
This package comes with several most common `Validator`s and `FormFieldValidator`s such as required, numeric, mail,
377386
URL, min, max, minLength, maxLength, minWordsCount, maxWordsCount, IP, credit card, etc., with default `errorText` messages.
378387

379388
- But what is a `FormFieldValidator`?
@@ -476,11 +485,74 @@ We welcome efforts to internationalize/localize the package by translating the d
476485

477486
#### Add new validator
478487

479-
1. Add a new validator to one of the folders in the `src` folder.
480-
2. Implement it using the `BaseValidator` or `TranslatedValidator` class. Override the `validateValue` method and let the base class handle the null check in the `validate` method.
481-
3. When using a `TranslatedValidator, Override the `translatedErrorText` property and return the correct translation from `FormBuilderLocalizations.current.`.
482-
4. Make sure to pass `errorText` and `checkNullOrEmpty` to the base class.
483-
5. Add static method to `form_builder_validators.dart` that uses the new validator.
488+
1. Add a new validator to one of the folders in the `src/validators` folder.
489+
2. Implement it as a function which returns `Validator<T>` with `T` being the type of
490+
the user input to be validated.
491+
3. Add the @macro tag for documentation using the template name: `validator_<validator_snake_case_name>`.
492+
This will refer to the actual documentation, which will be on the `Validators` static method.
493+
4. If your validator uses localized error message, you can use `FormBuilderLocalizations.current.<name_of_localized_message>`
494+
Next we have the example of the numeric validator `greaterThan`. As we can see, it has its `@macro` docstring, it uses a
495+
localized error message (`FormBuilderLocalizations.current.greaterThanErrorText(reference)`) and it returns
496+
`Validator<T extends num>`:
497+
```dart
498+
/// {@macro validator_greater_than}
499+
Validator<T> greaterThan<T extends num>(T reference,
500+
{String Function(T input, T reference)? greaterThanMsg}) {
501+
return (T input) {
502+
return input > reference
503+
? null
504+
: greaterThanMsg?.call(input, reference) ??
505+
FormBuilderLocalizations.current.greaterThanErrorText(reference);
506+
};
507+
}
508+
```
509+
5. Add the validator as static method to `form_builder_validators.dart` in the `Validators` class. Do
510+
not forget to add documentation to the new static method, using the `@template` element to give a name
511+
to the docstring. Follow the pattern: `validator_<validator_snake_case_name>`.
512+
Here, an example of how to add the static method of the validator to the `Validators` class:
513+
```dart
514+
final class Validators{
515+
//Other validators...
516+
517+
/// {@template validator_greater_than}
518+
/// Creates a validator function that checks if a numeric input exceeds `reference`.
519+
///
520+
/// ## Type Parameters
521+
/// - `T`: A numeric type that extends [num], allowing `int`, `double` or
522+
/// `num` validations
523+
///
524+
/// ## Parameters
525+
/// - `reference` (`T`): The threshold value that the input must exceed
526+
/// - `greaterThanMsg` (`String Function(T input, T reference)?`): Optional custom error
527+
/// message generator that takes the input value and threshold as parameters
528+
///
529+
/// ## Returns
530+
/// Returns a [Validator] function that:
531+
/// - Returns `null` if the input is greater than the threshold value `reference`
532+
/// - Returns an error message string if validation fails, either from the custom
533+
/// `greaterThanMsg` function or the default localized error text
534+
///
535+
/// ## Examples
536+
/// ```dart
537+
/// // Basic usage with integers
538+
/// final ageValidator = greaterThan<int>(18);
539+
///
540+
/// // Custom error message
541+
/// final priceValidator = greaterThan<double>(
542+
/// 0.0,
543+
/// greaterThanMsg: (_, ref) => 'Price must be greater than \$${ref.toStringAsFixed(2)}',
544+
/// );
545+
/// ```
546+
///
547+
/// ## Caveats
548+
/// - The validator uses strict greater than comparison (`>`)
549+
/// {@endtemplate}
550+
static Validator<T> greaterThan<T extends c.num>(T reference,
551+
{String Function(c.num input, c.num reference)? greaterThanMsg}) =>
552+
val.greaterThan(reference, greaterThanMsg: greaterThanMsg);
553+
}
554+
// OBS.: the core package is imported with prefix c to avoid name collision!
555+
```
484556
6. Implement tests
485557
7. Add to [validators](#validators) with name and description
486558
8. Add message error translated on all languages (yes, all languages). To accomplish this need:

0 commit comments

Comments
 (0)