Skip to content

Commit fb30d88

Browse files
authored
Merge pull request #5 from codem/update-validation
Update validation
2 parents fb25be5 + b8d56ec commit fb30d88

29 files changed

+755
-123
lines changed

README.md

+17-5
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ This module provides a set of bare bones HTML5 inputs with no Javascript or CSS.
44

55
You can use these fields in your projects as-is or extend them to provide additional features or shims.
66

7-
The supported inputs are listed at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input tagged 'HTML5'
7+
The supported inputs are listed at https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input:
88

99
+ colour (color)
10-
+ date, datetime, time
11-
+ email (extends core EmailField)
10+
+ date, datetime-local, time
11+
+ email (extends core Silverstripe EmailField)
1212
+ month, week
1313
+ number
1414
+ range
@@ -20,9 +20,22 @@ Browser support for these fields is varying although nearly all modern browsers
2020

2121
Date, datetime and time fields are particularly difficult to support, due to locale differences and even different user expectations within those locales.
2222

23+
## Traits
24+
25+
Various field types support certain traits that allow setting/getting of common attributes
26+
27+
+ Step - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#step
28+
+ DataList - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist
29+
+ Spellcheck - https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck
30+
+ Min/Max - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#min / max
31+
+ Pattern - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#pattern
32+
+ Multiple - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#multiple
33+
2334
### Datalist
2435

25-
Certain inputs support a `<datalist>`, [e.g the colour field](./docs/en/002_inputs.md) to restrict initial selection. Browser implementation varies.
36+
Certain inputs support a `<datalist>`, [e.g the colour field](./docs/en/002_inputs.md) to restrict initial selection.
37+
38+
This works somewhat like a `<select>` element, except that browser implementation and support varies.
2639

2740

2841
## Requirements
@@ -54,7 +67,6 @@ Hopefully none !
5467

5568
+ Codem
5669

57-
5870
## Bugtracker
5971

6072
Please use the Github issue tracker to report bugs and request features

src/Forms/ColorField.php

+92-17
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,62 @@
22

33
namespace Codem\Utilities\HTML5;
44

5-
use Silverstripe\Forms\TextField;
5+
use Silverstripe\Forms\FormField;
66
use SilverStripe\Forms\Validator;
77

88
/**
99
* Provides a colour picker / field
10+
*
1011
* @see https://www.w3.org/wiki/Html/Elements/input/color
1112
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color
1213
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color#Value wrt value
14+
* @see https://html.spec.whatwg.org/multipage/input.html#color-state-(type=color) (default colour)
15+
*
16+
* Default value
17+
* =============
18+
* The colour input is special in that it does not allow an empty value within the current spec.
19+
* The browser will always send through the default colour in the spec (#000000) if none is supplied
20+
*
21+
* In this implementation, the default field value set is static::WHITE
1322
*/
14-
class ColorField extends TextField
23+
class ColorField extends FormField
1524
{
1625

1726
use Core;
1827
use Datalist;
1928

29+
/**
30+
* @var string
31+
*/
32+
const WHITE = "#ffffff";
33+
34+
/**
35+
* @var string
36+
*/
2037
protected $inputType = 'color';
2138

22-
protected $defaultValue = "#ffffff";
39+
/**
40+
* This is the default colour for the input,
41+
* if no value is set, or if the value provided is not a valid hex colour string
42+
* On field construction this will be set to white
43+
* @var string|null
44+
*/
45+
protected $defaultValue = null;
46+
47+
/**
48+
* Returns a colour input field
49+
*
50+
* @param string $name
51+
* @param null|string $title
52+
* @param string $value
53+
* @param string $defaultValue the default value to use for the input
54+
*
55+
*/
56+
public function __construct($name, $title = null, $value = '', $defaultValue = '')
57+
{
58+
$this->setDefaultValue($defaultValue);
59+
parent::__construct($name, $title, $value);
60+
}
2361

2462
/**
2563
* Returns the value saved as a 6 chr RGB colour with # prefixed
@@ -42,18 +80,39 @@ public function Value()
4280
/**
4381
* When the value is set, handle incorrect values
4482
* @param string $value an RGB colour value as a 'valid simple colour'
45-
* @return void
4683
*/
4784
public function setValue($value, $data = null)
4885
{
4986
$this->value = $this->getValidRGB($value);
87+
return $this;
88+
}
89+
90+
91+
/**
92+
* Set the default value to be used if an invalid colour is detected
93+
* The default is static::WHITE
94+
*
95+
* @param string $defaultValue an RGB colour value as a 'valid simple colour'
96+
*/
97+
public function setDefaultValue(string $defaultValue) : self
98+
{
99+
$this->defaultValue = $this->getValidRGB($defaultValue);
100+
return $this;
101+
}
102+
103+
/**
104+
* Get the current default value
105+
*/
106+
public function getDefaultValue() : string
107+
{
108+
return $this->defaultValue;
50109
}
51110

52111
/**
53112
* Base on the value return either the defaultValue colour value or the value
54113
* @return string
55114
* @param string $value the value to check
56-
* @param Validator $validator optional, if set relevant errors will be added
115+
* @param Validator $validator optional, see isValidRGB
57116
*
58117
* The only valid value here is defined by the "valid simple colour" definition at
59118
* https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-simple-colour
@@ -64,15 +123,34 @@ public function setValue($value, $data = null)
64123
* representing the red component, the middle two digits representing the green component,
65124
* and the last two digits representing the blue component, in hexadecimal.</blockquote>
66125
*/
67-
public function getValidRGB($value, Validator $validator = null)
126+
public function getValidRGB(?string $value, Validator $validator = null) : string
68127
{
69128

70-
// empty values default to the empty value value
129+
$simpleColourValue = $this->defaultValue ?? static::WHITE;
130+
71131
if(!$value) {
72-
return $this->defaultValue;
132+
// no value provided .. return the defaultValue if set or WHITE
133+
return $simpleColourValue;
73134
}
74135

75136
$value = strtolower($value);
137+
if(!$this->isValidRGB($value, $validator)) {
138+
$value = $simpleColourValue;
139+
}
140+
141+
// Let result be a simple color.
142+
return $value;
143+
}
144+
145+
/**
146+
* Check if the value provided is a valid RGB value
147+
* @param string $value
148+
* @param Validator $validator an optional validator. If provided specific errors will be stored in the validator
149+
*/
150+
public function isValidRGB(?string $value, Validator $validator = null) : bool {
151+
152+
// Ensure a string value
153+
$value = $value ?? '';
76154

77155
// If input is not exactly seven characters long, then return an error.
78156
if(mb_strlen($value) != 7) {
@@ -86,7 +164,7 @@ public function getValidRGB($value, Validator $validator = null)
86164
"validation"
87165
);
88166
}
89-
return $this->defaultValue;
167+
return false;
90168
}
91169

92170
// If the first character in input is not a U+0023 NUMBER SIGN character (#), then return an error.
@@ -101,7 +179,7 @@ public function getValidRGB($value, Validator $validator = null)
101179
"validation"
102180
);
103181
}
104-
return $this->defaultValue;
182+
return false;
105183
}
106184

107185
// If the last six characters of input are not all ASCII hex digits, then return an error.
@@ -117,11 +195,11 @@ public function getValidRGB($value, Validator $validator = null)
117195
"validation"
118196
);
119197
}
120-
return $this->defaultValue;
198+
return false;
121199
}
122200

123-
// Let result be a simple color.
124-
return $value;
201+
// all tests pass
202+
return true;
125203
}
126204

127205
/**
@@ -132,10 +210,7 @@ public function getValidRGB($value, Validator $validator = null)
132210
*/
133211
public function validate($validator)
134212
{
135-
if(!$this->getValidRGB($this->value, $validator)) {
136-
return false;
137-
}
138-
return true;
213+
return $this->isValidRGB($this->Value(), $validator);
139214
}
140215

141216
}

src/Forms/DateField.php

+35-15
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,41 @@ class DateField extends TextField
1616
use Step;
1717
use MinMax;
1818

19+
/**
20+
* @inheritdoc
21+
*/
1922
protected $inputType = 'date';
2023

24+
/**
25+
* @var string
26+
*/
2127
protected $datetime_format = "Y-m-d";
2228

29+
/**
30+
* @var string
31+
*/
2332
protected $example = "2020-12-31";
2433

25-
protected function formatDate(\Datetime $datetime)
34+
/**
35+
* Format a date based on the field's formatr string
36+
*/
37+
protected function formatDate(\Datetime $datetime) : string
2638
{
2739
return $datetime->format($this->datetime_format);
2840
}
2941

30-
public function setMin(\DateTime $min)
42+
/**
43+
* Set minimum accepted date
44+
*/
45+
public function setMin(\DateTime $min) : self
3146
{
3247
return $this->setAttribute('min', $this->formatDate($min));
3348
}
3449

35-
public function setMax(\DateTime $max)
50+
/**
51+
* Set maximum accepted date
52+
*/
53+
public function setMax(\DateTime $max) : self
3654
{
3755
return $this->setAttribute('max', $this->formatDate($max));
3856
}
@@ -47,25 +65,27 @@ public function setMax(\DateTime $max)
4765
public function validate($validator)
4866
{
4967
try {
50-
$this->value = trim($this->value);
51-
$dt = new \Datetime($this->value);
68+
$value = trim($this->Value() ?? '');
69+
if($value === '') {
70+
// empty values are valid
71+
return true;
72+
}
73+
$dt = new \Datetime($value);
5274
$formatted = $this->formatDate($dt);
53-
if($formatted != $this->value) {
75+
if($formatted != $value) {
5476
throw new \Exception("Invalid date value passed");
5577
}
5678
return true;
5779
} catch (\Exception $e) {
5880
$validator->validationError(
5981
$this->name,
60-
sprintf(
61-
_t(
62-
'Codem\\Utilities\\HTML5\\DateField.VALIDATION',
63-
'Please enter a valid date in the format {format} (example:{example})',
64-
[
65-
'format' => $this->datetime_format,
66-
'example' => $this->example
67-
]
68-
)
82+
_t(
83+
'Codem\\Utilities\\HTML5\\DateField.VALIDATION',
84+
'Please enter a valid date in the format {format} (example:{example})',
85+
[
86+
'format' => $this->datetime_format,
87+
'example' => $this->example
88+
]
6989
),
7090
'validation'
7191
);

src/Forms/DatetimeField.php

+10
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,20 @@
1010
class DatetimeField extends DateField
1111
{
1212

13+
/**
14+
* @inheritdoc
15+
*/
1316
protected $inputType = 'datetime-local';
1417

18+
/**
19+
* @var string
20+
* The browser will always send the datetime in this format
21+
*/
1522
protected $datetime_format = "Y-m-d\TH:i";
1623

24+
/**
25+
* @var string
26+
*/
1727
protected $example = "2020-12-31T14:45";
1828

1929
}

src/Forms/NumberField.php

+7-4
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,20 @@ class NumberField extends TextField
2727
*/
2828
public function validate($validator)
2929
{
30-
$this->value = trim($this->value);
31-
32-
if (!is_numeric($this->value)) {
30+
$value = trim($this->Value() ?? '');
31+
if($value === '') {
32+
// empty values are valid
33+
return true;
34+
} else if (!is_numeric($value)) {
3335
$validator->validationError(
3436
$this->name,
3537
_t('Codem\\Utilities\\HTML5\\NumberField.VALIDATION', 'Please enter a number value'),
3638
'validation'
3739
);
3840
return false;
41+
} else {
42+
return true;
3943
}
40-
return true;
4144
}
4245

4346
}

0 commit comments

Comments
 (0)