diff --git a/lib/src/common_fields.dart b/lib/src/common_fields.dart index ef41bfa3..79222e8d 100644 --- a/lib/src/common_fields.dart +++ b/lib/src/common_fields.dart @@ -11,29 +11,46 @@ class TextField extends Field { /// If `true` (default), then the input will be trimmed before validation. final bool trim; + /// If not `null`, then if the value of [confirmedAs] in the body is not + /// identical, an error will be returned. + final String confirmedAs; + TextField(String name, {String label, bool isRequired = true, this.isTextArea = false, - this.trim = true}) + this.trim = true, + this.confirmedAs}) : super(name, label: label, isRequired: isRequired); @override FutureOr accept(FormRenderer renderer) => renderer.visitTextField(this); + String _normalize(String s) { + if (trim) { + s = s?.trim(); + } + return s; + } + @override FutureOr> read(RequestContext req, Map fields, Iterable files) { - var value = fields[name] as String; - if (trim) { - value = value?.trim(); - } + var value = _normalize(fields[name] as String); if (value == null) { return null; } else if (trim && value.isEmpty) { return null; } else { + if (confirmedAs != null) { + var confirmed = _normalize(fields[confirmedAs] as String); + if (confirmed != value) { + return FieldReadResult.failure( + ['"$name" and "$confirmedAs" must be identical.']); + } + } + return FieldReadResult.success(value); } }