Skip to content

Commit 968881a

Browse files
committed
Fixed url validator, added IP, creditCard and date validators
More tests
1 parent 71dc7a3 commit 968881a

File tree

7 files changed

+254
-170
lines changed

7 files changed

+254
-170
lines changed

.idea/libraries/Dart_Packages.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 157 additions & 154 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,6 @@ GlobalKey<FormBuilderState> _fbKey = GlobalKey();
288288
- [ ] Assert no duplicates in `FormBuilderInput`s `attribute` names
289289
- [ ] Allow options for Checkboxes and Radios to appear left or right
290290
- [ ] Allow addition of custom input types
291-
- [ ] Proper validation for URL - does not work without protocol - http(s)
292291

293292
### New FormBuilder inputs
294293
- [X] SignaturePad

lib/src/form_builder_validators.dart

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:flutter/material.dart';
2+
import 'package:validators/validators.dart';
23

34
class FormBuilderValidators {
45
/// [FormFieldValidator] that requires the field have a non-empty value.
@@ -93,22 +94,29 @@ class FormBuilderValidators {
9394
}) {
9495
return (val) {
9596
if (val != null && val.isNotEmpty) {
96-
Pattern pattern =
97-
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
98-
if (!RegExp(pattern).hasMatch(val)) return errorText;
97+
if (!isEmail(val)) return errorText;
9998
}
10099
};
101100
}
102101

103102
/// [FormFieldValidator] that requires the field's value to be a valid url.
104-
static FormFieldValidator url({
105-
String errorText = "This field requires a valid email address.",
106-
}) {
103+
static FormFieldValidator url(
104+
{String errorText = "This field requires a valid URL address.",
105+
List<String> protocols = const ['http', 'https', 'ftp'],
106+
bool requireTld = true,
107+
bool requireProtocol = false,
108+
bool allowUnderscore = false,
109+
List<String> hostWhitelist = const [],
110+
List<String> hostBlacklist = const []}) {
107111
return (val) {
108112
if (val != null && val.isNotEmpty) {
109-
Pattern pattern =
110-
r"(https?|ftp)://([-A-Z0-9.]+)(/[-A-Z0-9+&@#/%=~_|!:,.;]*)?(\?[A-Z0-9+&@#/%=~_|!:‌​,.;]*)?";
111-
if (!RegExp(pattern).hasMatch(val)) return errorText;
113+
if (!isURL(val,
114+
protocols: protocols,
115+
requireTld: requireTld,
116+
requireProtocol: requireProtocol,
117+
allowUnderscore: allowUnderscore,
118+
hostWhitelist: hostWhitelist,
119+
hostBlacklist: hostBlacklist)) return errorText;
112120
}
113121
};
114122
}
@@ -134,4 +142,39 @@ class FormBuilderValidators {
134142
if (num.tryParse(val) == null && val.isNotEmpty) return errorText;
135143
};
136144
}
145+
146+
/// [FormFieldValidator] that requires the field's value to be a valid credit card number.
147+
static FormFieldValidator creditCard({
148+
String errorText = "This field requires a valid credit card number.",
149+
}) {
150+
return (val) {
151+
if (val != null && val.isNotEmpty) {
152+
if (!isCreditCard(val)) return errorText;
153+
}
154+
};
155+
}
156+
157+
/// [FormFieldValidator] that requires the field's value to be a valid IP.
158+
// ignore: non_constant_identifier_names
159+
static FormFieldValidator IP({
160+
dynamic version,
161+
String errorText = "This field requires a valid IP.",
162+
}) {
163+
return (val) {
164+
if (val != null && val.isNotEmpty) {
165+
if (!isIP(val, version)) return errorText;
166+
}
167+
};
168+
}
169+
170+
/// [FormFieldValidator] that requires the field's value to be a valid date string.
171+
static FormFieldValidator date({
172+
String errorText = "This field requires a valid date string.",
173+
}) {
174+
return (val) {
175+
if (val != null && val.isNotEmpty) {
176+
if (!isDate(val)) return errorText;
177+
}
178+
};
179+
}
137180
}

pubspec.lock

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,13 @@ packages:
380380
url: "https://pub.dartlang.org"
381381
source: hosted
382382
version: "1.1.6"
383+
validators:
384+
dependency: "direct main"
385+
description:
386+
name: validators
387+
url: "https://pub.dartlang.org"
388+
source: hosted
389+
version: "2.0.0+1"
383390
vector_math:
384391
dependency: transitive
385392
description:

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies:
1818
datetime_picker_formfield: ^0.1.8
1919
signature: ^2.0.0
2020
expandable: ^2.0.0
21+
validators: ^2.0.0
2122

2223
dev_dependencies:
2324
flutter_test:

test/flutter_form_builder_test.dart

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,37 @@ void main() {
99
});
1010

1111
test('FormBuilderValidators.email', () {
12-
expect(FormBuilderValidators.email()("john@flutter"), equals("This field requires a valid email address."));
13-
expect(FormBuilderValidators.email()("[email protected]"), equals(null));
14-
expect(FormBuilderValidators.email()(null), equals(null));
15-
expect(FormBuilderValidators.email()(""), equals(null));
12+
expect(FormBuilderValidators.email()("john@flutter"), isNotNull);
13+
expect(FormBuilderValidators.email()("[email protected]"), isNull);
14+
expect(FormBuilderValidators.email()(null), isNull);
15+
expect(FormBuilderValidators.email()(""),isNull);
1616
});
1717

1818
test('FormBuilderValidators.max', () {
19-
expect(FormBuilderValidators.max(20)("70"), equals("Value must be less than or equal to 20"));
20-
expect(FormBuilderValidators.max(30)(70), equals("Value must be less than or equal to 30"));
19+
expect(FormBuilderValidators.max(20)("70"), isNotNull);
20+
expect(FormBuilderValidators.max(30)(70), isNotNull);
21+
expect(FormBuilderValidators.max(30)(20), isNull);
22+
});
23+
24+
test('FormBuilderValidators.min', () {
25+
expect(FormBuilderValidators.min(30)("10"), isNotNull);
26+
expect(FormBuilderValidators.min(30)(10), isNotNull);
27+
expect(FormBuilderValidators.min(30)(70), isNull);
28+
});
29+
30+
test('FormBuilderValidators.url', () {
31+
expect(FormBuilderValidators.url()(null), isNull);
32+
expect(FormBuilderValidators.url()("https://www.google.com"), isNull);
33+
expect(FormBuilderValidators.url()("www.google.com"), isNull);
34+
expect(FormBuilderValidators.url()("google.com"), isNull);
35+
expect(FormBuilderValidators.url()("http://google.com"), isNull);
36+
expect(FormBuilderValidators.url()(".com"), isNotNull);
37+
expect(FormBuilderValidators.url(protocols: ['https', 'http'], errorText: "Only HTTP and HTTPS allowed")("ftp://www.google.com"), isNotNull);
38+
});
39+
40+
test('FormBuilderValidators.IP', () {
41+
expect(FormBuilderValidators.IP()(null), isNull);
42+
expect(FormBuilderValidators.IP()("192.168.0.1"), isNull);
43+
expect(FormBuilderValidators.IP()("256.168.0.1"), isNotNull);
2144
});
2245
}

0 commit comments

Comments
 (0)