Skip to content

Commit d743dd9

Browse files
reneklimentdg
authored andcommitted
add Form::PATTERN_ICASE as a case-insensitive variant of Form::PATTERN; fixes #185 (#187)
1 parent e3b5529 commit d743dd9

File tree

5 files changed

+34
-6
lines changed

5 files changed

+34
-6
lines changed

src/Forms/Form.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Form extends Container implements Nette\Utils\IHtmlString
4646
EMAIL = ':email',
4747
URL = ':url',
4848
PATTERN = ':pattern',
49+
PATTERN_ICASE = ':patternCaseInsensitive',
4950
INTEGER = ':integer',
5051
NUMERIC = ':numeric',
5152
FLOAT = ':float',

src/Forms/Validator.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,19 @@ public static function validateUrl(IControl $control): bool
246246

247247

248248
/**
249-
* Matches control's value regular expression?
249+
* Does the control's value match the regular expression?
250+
* Case-sensitive to comply with the HTML5 <input /> pattern attribute behaviour
250251
*/
251-
public static function validatePattern(IControl $control, string $pattern): bool
252+
public static function validatePattern(IControl $control, string $pattern, bool $caseInsensitive = false): bool
252253
{
253254
$value = $control->getValue() instanceof Nette\Http\FileUpload ? $control->getValue()->getName() : $control->getValue();
254-
return (bool) Strings::match($value, "\x01^(?:$pattern)\\z\x01u");
255+
return (bool) Strings::match($value, "\x01^(?:$pattern)\\z\x01u" . ($caseInsensitive ? 'i' : ''));
256+
}
257+
258+
259+
public static function validatePatternCaseInsensitive(IControl $control, string $pattern): bool
260+
{
261+
return self::validatePattern($control, $pattern, true);
255262
}
256263

257264

src/assets/netteForms.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,16 +448,16 @@
448448
} catch (e) {} // eslint-disable-line no-empty
449449
},
450450

451-
pattern: function(elem, arg, val) {
451+
pattern: function(elem, arg, val, value, caseInsensitive) {
452452
if (typeof arg !== 'string') {
453453
return null;
454454
}
455455

456456
try {
457457
try {
458-
var regExp = new RegExp('^(?:' + arg + ')$', 'u');
458+
var regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'ui' : 'u');
459459
} catch (e) {
460-
regExp = new RegExp('^(?:' + arg + ')$');
460+
regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'i' : '');
461461
}
462462

463463
if (window.FileList && val instanceof FileList) {
@@ -474,6 +474,10 @@
474474
} catch (e) {} // eslint-disable-line no-empty
475475
},
476476

477+
patternCaseInsensitive: function(elem, arg, val) {
478+
return Nette.validators.pattern(elem, arg, val, null, true);
479+
},
480+
477481
numeric: function(elem, arg, val) {
478482
if (elem.type === 'number' && elem.validity.badInput) {
479483
return false;

tests/Forms/Controls.TestBase.validators.phpt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ test(function () {
9595
Assert::false(Validator::validatePattern($control, '[0-9]+X'));
9696
});
9797

98+
test(function () {
99+
$control = new TextInput;
100+
$control->value = '123x';
101+
Assert::false(Validator::validatePatternCaseInsensitive($control, '[0-9]'));
102+
Assert::true(Validator::validatePatternCaseInsensitive($control, '[0-9]+x'));
103+
Assert::true(Validator::validatePatternCaseInsensitive($control, '[0-9]+X'));
104+
});
105+
98106

99107
test(function () {
100108
class MockUploadControl extends UploadControl

tests/netteForms/spec/Nette.validateRuleSpec.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ describe('Nette.getValue & validateRule', function() {
4545
expect(Nette.validateRule(el, 'pattern', '\\d')).toBe(false);
4646
expect(Nette.validateRule(el, 'pattern', '\\w')).toBe(false);
4747
expect(Nette.validateRule(el, 'pattern', '\\w+')).toBe(true);
48+
expect(Nette.validateRule(el, 'pattern', 'hello')).toBe(true);
49+
expect(Nette.validateRule(el, 'pattern', 'HELLO')).toBe(false);
50+
expect(Nette.validateRule(el, 'patternCaseInsensitive', '\\d+')).toBe(false);
51+
expect(Nette.validateRule(el, 'patternCaseInsensitive', '\\d')).toBe(false);
52+
expect(Nette.validateRule(el, 'patternCaseInsensitive', '\\w')).toBe(false);
53+
expect(Nette.validateRule(el, 'patternCaseInsensitive', '\\w+')).toBe(true);
54+
expect(Nette.validateRule(el, 'patternCaseInsensitive', 'hello')).toBe(true);
55+
expect(Nette.validateRule(el, 'patternCaseInsensitive', 'HELLO')).toBe(true);
4856
expect(Nette.validateRule(el, 'integer')).toBe(false);
4957
expect(Nette.validateRule(el, 'float')).toBe(false);
5058

0 commit comments

Comments
 (0)