@@ -356,14 +356,54 @@ class FormBuilderValidators {
356
356
: null ;
357
357
358
358
/// [FormFieldValidator] that requires the field's value to be a valid date string.
359
- static FormFieldValidator <String > dateString ({
359
+ static FormFieldValidator <String > date ({
360
360
String ? errorText,
361
361
}) =>
362
362
(valueCandidate) => true == valueCandidate? .isNotEmpty &&
363
363
! isDate (valueCandidate! )
364
364
? errorText ?? FormBuilderLocalizations .current.dateStringErrorText
365
365
: null ;
366
366
367
+ /// [FormFieldValidator] that requires the field's value to be a date within a certain range.
368
+ static FormFieldValidator <String > dateRange ({
369
+ required String minDate,
370
+ required String maxDate,
371
+ String ? errorText,
372
+ }) {
373
+ return compose <String >(
374
+ [
375
+ minDate.isNotEmpty
376
+ ? date (errorText: errorText)
377
+ : (valueCandidate) => null ,
378
+ maxDate.isNotEmpty
379
+ ? date (errorText: errorText)
380
+ : (valueCandidate) => null ,
381
+ (valueCandidate) {
382
+ if (valueCandidate == null || valueCandidate.isEmpty) {
383
+ return null ;
384
+ }
385
+
386
+ final minDateTime = DateTime .tryParse (minDate);
387
+ final maxDateTime = DateTime .tryParse (maxDate);
388
+ final valueDateTime = DateTime .tryParse (valueCandidate);
389
+
390
+ if (minDateTime != null &&
391
+ valueDateTime! .isBefore (minDateTime) &&
392
+ maxDateTime != null &&
393
+ valueDateTime.isAfter (maxDateTime)) {
394
+ return errorText ??
395
+ FormBuilderLocalizations .current.dateRangeErrorText (
396
+ minDate,
397
+ maxDate,
398
+ );
399
+ }
400
+
401
+ return null ;
402
+ },
403
+ ],
404
+ );
405
+ }
406
+
367
407
/// [FormFieldValidator] that requires the field's value to be a valid phone number.
368
408
static FormFieldValidator <String > phoneNumber ({
369
409
String ? errorText,
@@ -404,6 +444,7 @@ class FormBuilderValidators {
404
444
? errorText ?? FormBuilderLocalizations .current.lowercaseErrorText
405
445
: null ;
406
446
447
+ /// [FormFieldValidator] that requires the field's value to be a valid file extension.
407
448
static FormFieldValidator <File > fileExtension ({
408
449
required List <String > allowedExtensions,
409
450
String ? errorText,
@@ -416,4 +457,43 @@ class FormBuilderValidators {
416
457
FormBuilderLocalizations .current
417
458
.fileExtensionErrorText (allowedExtensions.join (', ' ))
418
459
: null ;
460
+
461
+ /// [FormFieldValidator] that restricts the size of an file to be less than or equal to the provided maximum size.
462
+ /// * [maxSize] is the maximum size in bytes.
463
+ static FormFieldValidator <File > fileSize ({
464
+ required int maxSize,
465
+ String ? errorText,
466
+ }) =>
467
+ (File ? valueCandidate) => valueCandidate == null
468
+ ? null
469
+ : valueCandidate.existsSync () && valueCandidate.lengthSync () > maxSize
470
+ ? errorText ??
471
+ FormBuilderLocalizations .current.fileSizeErrorText (
472
+ formatBytes (valueCandidate.lengthSync ()),
473
+ formatBytes (maxSize),
474
+ )
475
+ : null ;
476
+
477
+ /// [FormFieldValidator] that applies another validator conditionally.
478
+ static FormFieldValidator <T > conditional <T >(
479
+ bool Function (T value) condition,
480
+ FormFieldValidator <T > validator,
481
+ ) =>
482
+ (T ? valueCandidate) =>
483
+ condition (valueCandidate as T ) ? validator (valueCandidate) : null ;
484
+
485
+ /// [FormFieldValidator] that requires the field's value to be within a certain range.
486
+ static FormFieldValidator <T > range <T >(
487
+ num minValue,
488
+ num maxValue, {
489
+ bool inclusive = true ,
490
+ String ? errorText,
491
+ }) {
492
+ return compose <T >(
493
+ [
494
+ min (minValue, inclusive: inclusive, errorText: errorText),
495
+ max (maxValue, inclusive: inclusive, errorText: errorText),
496
+ ],
497
+ );
498
+ }
419
499
}
0 commit comments