hof 20.1.3 → 20.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/controller/validation/validators.js +4 -0
- package/frontend/template-mixins/mixins/template-mixins.js +11 -0
- package/frontend/template-mixins/partials/forms/textarea-group.html +35 -32
- package/package.json +2 -2
- package/sandbox/apps/sandbox/fields.js +16 -7
- package/sandbox/apps/sandbox/index.js +4 -0
- package/sandbox/apps/sandbox/sections/summary-data-sections.js +3 -0
- package/sandbox/apps/sandbox/translations/src/en/fields.json +6 -2
- package/sandbox/apps/sandbox/translations/src/en/pages.json +9 -0
- package/sandbox/apps/sandbox/translations/src/en/validation.json +4 -0
package/README.md
CHANGED
@@ -1530,6 +1530,7 @@ To render a specific fields in your templates use the mixin name (matching those
|
|
1530
1530
|
- `required`: Value applied to `aria-required` HTML attribute.
|
1531
1531
|
- `hint`: This adds context to the label, which it is a part of, for input text, radio groups and textarea. It is used within the input by aria-describedby for screen readers.
|
1532
1532
|
- `maxlength`: Applicable to text-based fields and mapped to the `maxlength` HTML attribute.
|
1533
|
+
- `maxword`: Applicable to textarea fields.
|
1533
1534
|
- `options`: Applicable to HTML `select` and `radio` controls and used to generate the items of either HTML element.
|
1534
1535
|
- `selected`: Applicable to `select`, `checkbox`, and `radio` controls. Will render the selected HTML option/element selected or checked.
|
1535
1536
|
- `legend`: Applicable to `radio` button controls, which are wrapped in a HTML `fieldset` with a `legend` element.
|
@@ -62,6 +62,10 @@ module.exports = Validators = {
|
|
62
62
|
return Validators.string(value) && (value === '' || value.length <= length);
|
63
63
|
},
|
64
64
|
|
65
|
+
maxword(value, length) {
|
66
|
+
return Validators.string(value) && (value === '' || value.split(/\s+/).length <= length);
|
67
|
+
},
|
68
|
+
|
65
69
|
exactlength(value, length) {
|
66
70
|
return Validators.string(value) && (value === '' || value.length === length);
|
67
71
|
},
|
@@ -42,6 +42,15 @@ module.exports = function (options) {
|
|
42
42
|
return null;
|
43
43
|
}
|
44
44
|
|
45
|
+
function maxword(field) {
|
46
|
+
const validation = field.validate || [];
|
47
|
+
const mw = _.findWhere(validation, { type: 'maxword' });
|
48
|
+
if (mw) {
|
49
|
+
return _.isArray(mw.arguments) ? mw.arguments[0] : mw.arguments;
|
50
|
+
}
|
51
|
+
return null;
|
52
|
+
}
|
53
|
+
|
45
54
|
function type(field) {
|
46
55
|
return field.type || 'text';
|
47
56
|
}
|
@@ -208,6 +217,7 @@ module.exports = function (options) {
|
|
208
217
|
hintId: extension.hintId || (hint ? key + '-hint' : null),
|
209
218
|
error: this.errors && this.errors[key],
|
210
219
|
maxlength: maxlength(field) || extension.maxlength,
|
220
|
+
maxword: maxword(field) || extension.maxword,
|
211
221
|
required: required,
|
212
222
|
pattern: extension.pattern,
|
213
223
|
date: extension.date,
|
@@ -216,6 +226,7 @@ module.exports = function (options) {
|
|
216
226
|
isPageHeading: field.isPageHeading,
|
217
227
|
attributes: field.attributes,
|
218
228
|
isPrefixOrSuffix: _.map(field.attributes, item => {if (item.prefix || item.suffix !== undefined) return true;}),
|
229
|
+
isMaxlengthOrMaxword: maxlength(field) || extension.maxlength || maxword(field) || extension.maxword,
|
219
230
|
renderChild: renderChild.bind(this)
|
220
231
|
});
|
221
232
|
}
|
@@ -1,32 +1,35 @@
|
|
1
|
-
{{#
|
2
|
-
|
3
|
-
{{/
|
4
|
-
<div id="{{id}}-group" class="
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
id="{{id}}"
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
{{
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
1
|
+
{{#isMaxlengthOrMaxword}}<div class="govuk-character-count" data-module="govuk-character-count"
|
2
|
+
{{#maxlength}}data-maxlength="{{maxlength}}" {{/maxlength}} {{#maxword}}data-maxwords="{{maxword}}" {{/maxword}}>
|
3
|
+
{{/isMaxlengthOrMaxword}}
|
4
|
+
<div id="{{id}}-group" class="govuk-form-group {{#formGroupClassName}}{{formGroupClassName}}{{/formGroupClassName}}{{#error}} govuk-form-group--error{{/error}}">
|
5
|
+
{{#isPageHeading}}<h1 class="govuk-label-wrapper">{{/isPageHeading}}
|
6
|
+
<label for="{{id}}"
|
7
|
+
class="{{labelClassName}}{{#isPageHeading}}govuk-label--l{{/isPageHeading}}">
|
8
|
+
{{{label}}}
|
9
|
+
{{#error}}
|
10
|
+
<p id="{{id}}-error" class="govuk-error-message">
|
11
|
+
<span id="{{id}}-error" class="govuk-visually-hidden">Error:</span>{{error.message}}
|
12
|
+
</p>
|
13
|
+
{{/error}}
|
14
|
+
</label>
|
15
|
+
{{#isPageHeading}}</h1>{{/isPageHeading}}
|
16
|
+
{{#hint}}<div {{$hintId}}id="{{hintId}}" {{/hintId}}class="govuk-hint">{{hint}}</div>{{/hint}}
|
17
|
+
{{#renderChild}}{{/renderChild}}
|
18
|
+
<textarea name="{{id}}" id="{{id}}"
|
19
|
+
class="govuk-textarea {{#isMaxlengthOrMaxword}}govuk-js-character-count{{/isMaxlengthOrMaxword}} {{#className}}{{className}}{{/className}} {{#error}}govuk-input--error{{/error}}"
|
20
|
+
aria-describedby="{{id}}-info"
|
21
|
+
{{#attributes}}
|
22
|
+
{{attribute}}="{{value}}"
|
23
|
+
{{/attributes}}
|
24
|
+
{{^error}}{{#hintId}}{{#maxlength}} aria-describedby="{{id}}-maxlength-hint {{hintId}}"{{/maxlength}}{{/hintId}}{{/error}}
|
25
|
+
{{^error}}{{#hintId}}{{^maxlength}} aria-describedby="{{hintId}}"{{/maxlength}}{{/hintId}}{{/error}}
|
26
|
+
{{^error}}{{^hintId}}{{#maxlength}}aria-describedby="{{id}}-maxlength-hint" {{/maxlength}}{{/hintId}}{{/error}}
|
27
|
+
{{#error}} aria-invalid="true" aria-describedby="{{id}}-error" {{/error}}
|
28
|
+
>{{value}}</textarea>
|
29
|
+
{{#isMaxlengthOrMaxword}}
|
30
|
+
<div id="{{id}}-info" class=" govuk-hint govuk-character-count__message" aria-live="polite">You have {{#maxlength}}{{maxlength}} characters{{/maxlength}}{{#maxword}}{{maxword}}
|
31
|
+
words{{/maxword}} remaining
|
32
|
+
</div>
|
33
|
+
{{/isMaxlengthOrMaxword}}
|
34
|
+
</div>
|
35
|
+
{{#isMaxlengthOrMaxword}}</div>{{/isMaxlengthOrMaxword}}
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "hof",
|
3
3
|
"description": "A bootstrap for HOF projects",
|
4
|
-
"version": "20.1.
|
4
|
+
"version": "20.1.4",
|
5
5
|
"license": "MIT",
|
6
6
|
"main": "index.js",
|
7
7
|
"author": "HomeOffice",
|
@@ -135,7 +135,7 @@
|
|
135
135
|
"reporter": "spec",
|
136
136
|
"require": "test/common.js",
|
137
137
|
"recursive": "true",
|
138
|
-
"timeout": "
|
138
|
+
"timeout": "7000",
|
139
139
|
"exit": "true"
|
140
140
|
},
|
141
141
|
"resolutions": {
|
@@ -16,9 +16,6 @@ module.exports = {
|
|
16
16
|
},
|
17
17
|
name: {
|
18
18
|
validate: ['required', 'notUrl', { type: 'maxlength', arguments: 200 }],
|
19
|
-
// need to remove this for the heading to go
|
20
|
-
labelClassName: ['govuk-label--l'],
|
21
|
-
isPageHeading: 'true'
|
22
19
|
},
|
23
20
|
'dateOfBirth': dateComponent('dateOfBirth', {
|
24
21
|
mixin: 'input-date',
|
@@ -70,8 +67,6 @@ module.exports = {
|
|
70
67
|
]
|
71
68
|
},
|
72
69
|
email: {
|
73
|
-
isPageHeading: 'true',
|
74
|
-
labelClassName: ['govuk-label--l'],
|
75
70
|
validate: ['required', 'email']
|
76
71
|
},
|
77
72
|
phone: {
|
@@ -95,11 +90,10 @@ module.exports = {
|
|
95
90
|
mixin: 'textarea',
|
96
91
|
// we want to ignore default formatters as we want
|
97
92
|
// to preserve white space
|
98
|
-
isPageHeading: 'true',
|
99
93
|
'ignore-defaults': true,
|
100
94
|
// apply the other default formatters
|
101
95
|
formatter: ['trim', 'hyphens'],
|
102
|
-
|
96
|
+
isPageHeading: 'true',
|
103
97
|
// attributes here are passed to the field element
|
104
98
|
validate: ['required', { type: 'maxlength', arguments: 10 }],
|
105
99
|
attributes: [{
|
@@ -107,6 +101,21 @@ module.exports = {
|
|
107
101
|
value: 8
|
108
102
|
}]
|
109
103
|
},
|
104
|
+
whatHappened: {
|
105
|
+
mixin: 'textarea',
|
106
|
+
// we want to ignore default formatters as we want
|
107
|
+
// to preserve white space
|
108
|
+
'ignore-defaults': true,
|
109
|
+
// apply the other default formatters
|
110
|
+
formatter: ['trim', 'hyphens'],
|
111
|
+
isPageHeading: 'true',
|
112
|
+
// attributes here are passed to the field element
|
113
|
+
validate: ['required', { type: 'maxword', arguments: 10 }],
|
114
|
+
attributes: [{
|
115
|
+
attribute: 'rows',
|
116
|
+
value: 8
|
117
|
+
}]
|
118
|
+
},
|
110
119
|
appealStages: {
|
111
120
|
mixin: 'select',
|
112
121
|
isPageHeading: 'true',
|
@@ -15,7 +15,7 @@
|
|
15
15
|
}
|
16
16
|
},
|
17
17
|
"name": {
|
18
|
-
"label": "
|
18
|
+
"label": "Full name"
|
19
19
|
},
|
20
20
|
"dateOfBirth": {
|
21
21
|
"legend": "What is your date of birth?",
|
@@ -70,7 +70,7 @@
|
|
70
70
|
}
|
71
71
|
},
|
72
72
|
"email" : {
|
73
|
-
"label": "
|
73
|
+
"label": "Email address"
|
74
74
|
},
|
75
75
|
"phone": {
|
76
76
|
"label": "Phone number",
|
@@ -83,6 +83,10 @@
|
|
83
83
|
"label": "Complaint details",
|
84
84
|
"hint": "Briefly summarise your complaint. Include anything that can help our investigation."
|
85
85
|
},
|
86
|
+
"whatHappened": {
|
87
|
+
"label": "What happened",
|
88
|
+
"hint": "Briefly summarise what happened."
|
89
|
+
},
|
86
90
|
"countrySelect": {
|
87
91
|
"label": "Which country are you based in?",
|
88
92
|
"hint": "Start to type the country name and options will appear"
|
@@ -10,6 +10,12 @@
|
|
10
10
|
"header": "What is your address in the UK?",
|
11
11
|
"intro": "If you have no fixed address, enter an address where we can contact you."
|
12
12
|
},
|
13
|
+
"name": {
|
14
|
+
"header": "What is your full name?"
|
15
|
+
},
|
16
|
+
"email": {
|
17
|
+
"header": "Enter your email address"
|
18
|
+
},
|
13
19
|
"phone-number": {
|
14
20
|
"header": "Enter your phone number"
|
15
21
|
},
|
@@ -36,6 +42,9 @@
|
|
36
42
|
},
|
37
43
|
"complaintDetails": {
|
38
44
|
"header": "Complaint details"
|
45
|
+
},
|
46
|
+
"whatHappened": {
|
47
|
+
"header": "What happened"
|
39
48
|
}
|
40
49
|
}
|
41
50
|
},
|
@@ -44,6 +44,10 @@
|
|
44
44
|
"default": "Enter details about why you are making a complaint",
|
45
45
|
"maxlength": "Keep to the {{maxlength}} character limit"
|
46
46
|
},
|
47
|
+
"whatHappened": {
|
48
|
+
"default": "Enter details about what happened",
|
49
|
+
"maxword": "Keep to the {{maxword}} word limit"
|
50
|
+
},
|
47
51
|
"appealStages": {
|
48
52
|
"required": "Select an appeal stage from the list"
|
49
53
|
}
|