@ministryofjustice/frontend 5.0.0 → 5.1.0
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/moj/all.bundle.js +1549 -1062
- package/moj/all.bundle.js.map +1 -1
- package/moj/all.bundle.mjs +1845 -1054
- package/moj/all.bundle.mjs.map +1 -1
- package/moj/all.mjs +7 -90
- package/moj/all.mjs.map +1 -1
- package/moj/all.scss +1 -0
- package/moj/all.scss.map +1 -1
- package/moj/common/index.mjs +57 -0
- package/moj/common/index.mjs.map +1 -0
- package/moj/common/moj-frontend-version.mjs +14 -0
- package/moj/common/moj-frontend-version.mjs.map +1 -0
- package/moj/components/add-another/add-another.bundle.js +105 -76
- package/moj/components/add-another/add-another.bundle.js.map +1 -1
- package/moj/components/add-another/add-another.bundle.mjs +222 -71
- package/moj/components/add-another/add-another.bundle.mjs.map +1 -1
- package/moj/components/add-another/add-another.mjs +103 -72
- package/moj/components/add-another/add-another.mjs.map +1 -1
- package/moj/components/alert/alert.bundle.js +115 -191
- package/moj/components/alert/alert.bundle.js.map +1 -1
- package/moj/components/alert/alert.bundle.mjs +354 -186
- package/moj/components/alert/alert.bundle.mjs.map +1 -1
- package/moj/components/alert/alert.mjs +55 -140
- package/moj/components/alert/alert.mjs.map +1 -1
- package/moj/components/button-menu/README.md +3 -1
- package/moj/components/button-menu/button-menu.bundle.js +91 -120
- package/moj/components/button-menu/button-menu.bundle.js.map +1 -1
- package/moj/components/button-menu/button-menu.bundle.mjs +329 -114
- package/moj/components/button-menu/button-menu.bundle.mjs.map +1 -1
- package/moj/components/button-menu/button-menu.mjs +89 -116
- package/moj/components/button-menu/button-menu.mjs.map +1 -1
- package/moj/components/date-picker/date-picker.bundle.js +174 -154
- package/moj/components/date-picker/date-picker.bundle.js.map +1 -1
- package/moj/components/date-picker/date-picker.bundle.mjs +411 -147
- package/moj/components/date-picker/date-picker.bundle.mjs.map +1 -1
- package/moj/components/date-picker/date-picker.mjs +172 -150
- package/moj/components/date-picker/date-picker.mjs.map +1 -1
- package/moj/components/filter/template.njk +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js +133 -44
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.js.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs +374 -41
- package/moj/components/filter-toggle-button/filter-toggle-button.bundle.mjs.map +1 -1
- package/moj/components/filter-toggle-button/filter-toggle-button.mjs +131 -40
- package/moj/components/filter-toggle-button/filter-toggle-button.mjs.map +1 -1
- package/moj/components/form-validator/form-validator.bundle.js +159 -69
- package/moj/components/form-validator/form-validator.bundle.js.map +1 -1
- package/moj/components/form-validator/form-validator.bundle.mjs +399 -65
- package/moj/components/form-validator/form-validator.bundle.mjs.map +1 -1
- package/moj/components/form-validator/form-validator.mjs +134 -54
- package/moj/components/form-validator/form-validator.mjs.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.bundle.js +291 -117
- package/moj/components/multi-file-upload/multi-file-upload.bundle.js.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs +527 -109
- package/moj/components/multi-file-upload/multi-file-upload.bundle.mjs.map +1 -1
- package/moj/components/multi-file-upload/multi-file-upload.mjs +288 -101
- package/moj/components/multi-file-upload/multi-file-upload.mjs.map +1 -1
- package/moj/components/multi-file-upload/template.njk +1 -1
- package/moj/components/multi-select/multi-select.bundle.js +106 -41
- package/moj/components/multi-select/multi-select.bundle.js.map +1 -1
- package/moj/components/multi-select/multi-select.bundle.mjs +346 -37
- package/moj/components/multi-select/multi-select.bundle.mjs.map +1 -1
- package/moj/components/multi-select/multi-select.mjs +104 -37
- package/moj/components/multi-select/multi-select.mjs.map +1 -1
- package/moj/components/password-reveal/_password-reveal.scss +3 -1
- package/moj/components/password-reveal/_password-reveal.scss.map +1 -1
- package/moj/components/password-reveal/password-reveal.bundle.js +32 -29
- package/moj/components/password-reveal/password-reveal.bundle.js.map +1 -1
- package/moj/components/password-reveal/password-reveal.bundle.mjs +149 -24
- package/moj/components/password-reveal/password-reveal.bundle.mjs.map +1 -1
- package/moj/components/password-reveal/password-reveal.mjs +30 -25
- package/moj/components/password-reveal/password-reveal.mjs.map +1 -1
- package/moj/components/rich-text-editor/README.md +4 -3
- package/moj/components/rich-text-editor/rich-text-editor.bundle.js +127 -62
- package/moj/components/rich-text-editor/rich-text-editor.bundle.js.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs +367 -58
- package/moj/components/rich-text-editor/rich-text-editor.bundle.mjs.map +1 -1
- package/moj/components/rich-text-editor/rich-text-editor.mjs +125 -58
- package/moj/components/rich-text-editor/rich-text-editor.mjs.map +1 -1
- package/moj/components/search-toggle/search-toggle.bundle.js +94 -26
- package/moj/components/search-toggle/search-toggle.bundle.js.map +1 -1
- package/moj/components/search-toggle/search-toggle.bundle.mjs +334 -22
- package/moj/components/search-toggle/search-toggle.bundle.mjs.map +1 -1
- package/moj/components/search-toggle/search-toggle.mjs +92 -22
- package/moj/components/search-toggle/search-toggle.mjs.map +1 -1
- package/moj/components/sortable-table/sortable-table.bundle.js +151 -83
- package/moj/components/sortable-table/sortable-table.bundle.js.map +1 -1
- package/moj/components/sortable-table/sortable-table.bundle.mjs +390 -78
- package/moj/components/sortable-table/sortable-table.bundle.mjs.map +1 -1
- package/moj/components/sortable-table/sortable-table.mjs +149 -79
- package/moj/components/sortable-table/sortable-table.mjs.map +1 -1
- package/moj/core/_all.scss +3 -0
- package/moj/core/_all.scss.map +1 -0
- package/moj/core/_moj-frontend-properties.scss +7 -0
- package/moj/core/_moj-frontend-properties.scss.map +1 -0
- package/moj/filters/prototype-kit-13-filters.js +4 -3
- package/moj/helpers.bundle.js +22 -77
- package/moj/helpers.bundle.js.map +1 -1
- package/moj/helpers.bundle.mjs +23 -74
- package/moj/helpers.bundle.mjs.map +1 -1
- package/moj/helpers.mjs +23 -74
- package/moj/helpers.mjs.map +1 -1
- package/moj/moj-frontend.min.css +1 -1
- package/moj/moj-frontend.min.css.map +1 -1
- package/moj/moj-frontend.min.js +1 -1
- package/moj/moj-frontend.min.js.map +1 -1
- package/package.json +1 -1
- package/moj/version.bundle.js +0 -12
- package/moj/version.bundle.js.map +0 -1
- package/moj/version.bundle.mjs +0 -4
- package/moj/version.bundle.mjs.map +0 -1
- package/moj/version.mjs +0 -4
- package/moj/version.mjs.map +0 -1
|
@@ -1,120 +1,271 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
function isInitialised($root, moduleName) {
|
|
2
|
+
return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Checks if GOV.UK Frontend is supported on this page
|
|
7
|
+
*
|
|
8
|
+
* Some browsers will load and run our JavaScript but GOV.UK Frontend
|
|
9
|
+
* won't be supported.
|
|
10
|
+
*
|
|
11
|
+
* @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support
|
|
12
|
+
* @returns {boolean} Whether GOV.UK Frontend is supported on this page
|
|
13
|
+
*/
|
|
14
|
+
function isSupported($scope = document.body) {
|
|
15
|
+
if (!$scope) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return $scope.classList.contains('govuk-frontend-supported');
|
|
19
|
+
}
|
|
20
|
+
function formatErrorMessage(Component, message) {
|
|
21
|
+
return `${Component.moduleName}: ${message}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class GOVUKFrontendError extends Error {
|
|
25
|
+
constructor(...args) {
|
|
26
|
+
super(...args);
|
|
27
|
+
this.name = 'GOVUKFrontendError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
class SupportError extends GOVUKFrontendError {
|
|
31
|
+
/**
|
|
32
|
+
* Checks if GOV.UK Frontend is supported on this page
|
|
33
|
+
*
|
|
34
|
+
* @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support
|
|
35
|
+
*/
|
|
36
|
+
constructor($scope = document.body) {
|
|
37
|
+
const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class="govuk-frontend-supported">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';
|
|
38
|
+
super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type="module">`');
|
|
39
|
+
this.name = 'SupportError';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
class ElementError extends GOVUKFrontendError {
|
|
43
|
+
constructor(messageOrOptions) {
|
|
44
|
+
let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';
|
|
45
|
+
if (typeof messageOrOptions === 'object') {
|
|
46
|
+
const {
|
|
47
|
+
component,
|
|
48
|
+
identifier,
|
|
49
|
+
element,
|
|
50
|
+
expectedType
|
|
51
|
+
} = messageOrOptions;
|
|
52
|
+
message = identifier;
|
|
53
|
+
message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';
|
|
54
|
+
message = formatErrorMessage(component, message);
|
|
55
|
+
}
|
|
56
|
+
super(message);
|
|
57
|
+
this.name = 'ElementError';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
class InitError extends GOVUKFrontendError {
|
|
61
|
+
constructor(componentOrMessage) {
|
|
62
|
+
const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\`$root\`) already initialised`);
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = 'InitError';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
class Component {
|
|
69
|
+
/**
|
|
70
|
+
* Returns the root element of the component
|
|
71
|
+
*
|
|
72
|
+
* @protected
|
|
73
|
+
* @returns {RootElementType} - the root element of component
|
|
74
|
+
*/
|
|
75
|
+
get $root() {
|
|
76
|
+
return this._$root;
|
|
77
|
+
}
|
|
78
|
+
constructor($root) {
|
|
79
|
+
this._$root = void 0;
|
|
80
|
+
const childConstructor = this.constructor;
|
|
81
|
+
if (typeof childConstructor.moduleName !== 'string') {
|
|
82
|
+
throw new InitError(`\`moduleName\` not defined in component`);
|
|
6
83
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
84
|
+
if (!($root instanceof childConstructor.elementType)) {
|
|
85
|
+
throw new ElementError({
|
|
86
|
+
element: $root,
|
|
87
|
+
component: childConstructor,
|
|
88
|
+
identifier: 'Root element (`$root`)',
|
|
89
|
+
expectedType: childConstructor.elementType.name
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
this._$root = $root;
|
|
93
|
+
}
|
|
94
|
+
childConstructor.checkSupport();
|
|
95
|
+
this.checkInitialised();
|
|
96
|
+
const moduleName = childConstructor.moduleName;
|
|
97
|
+
this.$root.setAttribute(`data-${moduleName}-init`, '');
|
|
98
|
+
}
|
|
99
|
+
checkInitialised() {
|
|
100
|
+
const constructor = this.constructor;
|
|
101
|
+
const moduleName = constructor.moduleName;
|
|
102
|
+
if (moduleName && isInitialised(this.$root, moduleName)) {
|
|
103
|
+
throw new InitError(constructor);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
static checkSupport() {
|
|
107
|
+
if (!isSupported()) {
|
|
108
|
+
throw new SupportError();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @typedef ChildClass
|
|
115
|
+
* @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @typedef {typeof Component & ChildClass} ChildClassConstructor
|
|
120
|
+
*/
|
|
121
|
+
Component.elementType = HTMLElement;
|
|
122
|
+
|
|
123
|
+
class AddAnother extends Component {
|
|
124
|
+
/**
|
|
125
|
+
* @param {Element | null} $root - HTML element to use for add another
|
|
126
|
+
*/
|
|
127
|
+
constructor($root) {
|
|
128
|
+
super($root);
|
|
129
|
+
this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this));
|
|
130
|
+
this.$root.addEventListener('click', this.onAddButtonClick.bind(this));
|
|
131
|
+
const $buttons = this.$root.querySelectorAll('.moj-add-another__add-button, moj-add-another__remove-button');
|
|
132
|
+
$buttons.forEach($button => {
|
|
133
|
+
if (!($button instanceof HTMLButtonElement)) {
|
|
13
134
|
return;
|
|
14
135
|
}
|
|
15
|
-
button.type = 'button';
|
|
136
|
+
$button.type = 'button';
|
|
16
137
|
});
|
|
17
138
|
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @param {MouseEvent} event - Click event
|
|
142
|
+
*/
|
|
18
143
|
onAddButtonClick(event) {
|
|
19
|
-
const button = event.target;
|
|
20
|
-
if (
|
|
144
|
+
const $button = event.target;
|
|
145
|
+
if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__add-button')) {
|
|
21
146
|
return;
|
|
22
147
|
}
|
|
23
|
-
const items = this.getItems();
|
|
24
|
-
const item = this.getNewItem();
|
|
25
|
-
if (
|
|
148
|
+
const $items = this.getItems();
|
|
149
|
+
const $item = this.getNewItem();
|
|
150
|
+
if (!$item || !($item instanceof HTMLElement)) {
|
|
26
151
|
return;
|
|
27
152
|
}
|
|
28
|
-
this.updateAttributes(item, items.length);
|
|
29
|
-
this.resetItem(item);
|
|
30
|
-
const firstItem = items[0];
|
|
31
|
-
if (!this.hasRemoveButton(firstItem)) {
|
|
32
|
-
this.createRemoveButton(firstItem);
|
|
153
|
+
this.updateAttributes($item, $items.length);
|
|
154
|
+
this.resetItem($item);
|
|
155
|
+
const $firstItem = $items[0];
|
|
156
|
+
if (!this.hasRemoveButton($firstItem)) {
|
|
157
|
+
this.createRemoveButton($firstItem);
|
|
33
158
|
}
|
|
34
|
-
items[items.length - 1].after(item);
|
|
35
|
-
const input = item.querySelector('input, textarea, select');
|
|
36
|
-
if (input && input instanceof HTMLInputElement) {
|
|
37
|
-
input.focus();
|
|
159
|
+
$items[$items.length - 1].after($item);
|
|
160
|
+
const $input = $item.querySelector('input, textarea, select');
|
|
161
|
+
if ($input && $input instanceof HTMLInputElement) {
|
|
162
|
+
$input.focus();
|
|
38
163
|
}
|
|
39
164
|
}
|
|
40
|
-
|
|
41
|
-
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @param {HTMLElement} $item - Add another item
|
|
168
|
+
*/
|
|
169
|
+
hasRemoveButton($item) {
|
|
170
|
+
return $item.querySelectorAll('.moj-add-another__remove-button').length;
|
|
42
171
|
}
|
|
43
172
|
getItems() {
|
|
44
|
-
if (!this
|
|
173
|
+
if (!this.$root) {
|
|
45
174
|
return [];
|
|
46
175
|
}
|
|
47
|
-
const items = Array.from(this.
|
|
48
|
-
return items.filter(item => item instanceof HTMLElement);
|
|
176
|
+
const $items = Array.from(this.$root.querySelectorAll('.moj-add-another__item'));
|
|
177
|
+
return $items.filter(item => item instanceof HTMLElement);
|
|
49
178
|
}
|
|
50
179
|
getNewItem() {
|
|
51
|
-
const items = this.getItems();
|
|
52
|
-
const item = items[0].cloneNode(true);
|
|
53
|
-
if (
|
|
180
|
+
const $items = this.getItems();
|
|
181
|
+
const $item = $items[0].cloneNode(true);
|
|
182
|
+
if (!$item || !($item instanceof HTMLElement)) {
|
|
54
183
|
return;
|
|
55
184
|
}
|
|
56
|
-
if (!this.hasRemoveButton(item)) {
|
|
57
|
-
this.createRemoveButton(item);
|
|
185
|
+
if (!this.hasRemoveButton($item)) {
|
|
186
|
+
this.createRemoveButton($item);
|
|
58
187
|
}
|
|
59
|
-
return item;
|
|
188
|
+
return $item;
|
|
60
189
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* @param {HTMLElement} $item - Add another item
|
|
193
|
+
* @param {number} index - Add another item index
|
|
194
|
+
*/
|
|
195
|
+
updateAttributes($item, index) {
|
|
196
|
+
$item.querySelectorAll('[data-name]').forEach($input => {
|
|
197
|
+
if (!($input instanceof HTMLInputElement)) {
|
|
64
198
|
return;
|
|
65
199
|
}
|
|
66
|
-
const name =
|
|
67
|
-
const id =
|
|
68
|
-
const originalId =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const label =
|
|
72
|
-
if (label && label instanceof HTMLLabelElement) {
|
|
73
|
-
label.htmlFor =
|
|
200
|
+
const name = $input.getAttribute('data-name') || '';
|
|
201
|
+
const id = $input.getAttribute('data-id') || '';
|
|
202
|
+
const originalId = $input.id;
|
|
203
|
+
$input.name = name.replace(/%index%/, `${index}`);
|
|
204
|
+
$input.id = id.replace(/%index%/, `${index}`);
|
|
205
|
+
const $label = $input.parentElement.querySelector('label') || $input.closest('label') || $item.querySelector(`[for="${originalId}"]`);
|
|
206
|
+
if ($label && $label instanceof HTMLLabelElement) {
|
|
207
|
+
$label.htmlFor = $input.id;
|
|
74
208
|
}
|
|
75
209
|
});
|
|
76
210
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* @param {HTMLElement} $item - Add another item
|
|
214
|
+
*/
|
|
215
|
+
createRemoveButton($item) {
|
|
216
|
+
const $button = document.createElement('button');
|
|
217
|
+
$button.type = 'button';
|
|
218
|
+
$button.classList.add('govuk-button', 'govuk-button--secondary', 'moj-add-another__remove-button');
|
|
219
|
+
$button.textContent = 'Remove';
|
|
220
|
+
$item.append($button);
|
|
83
221
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* @param {HTMLElement} $item - Add another item
|
|
225
|
+
*/
|
|
226
|
+
resetItem($item) {
|
|
227
|
+
$item.querySelectorAll('[data-name], [data-id]').forEach($input => {
|
|
228
|
+
if (!($input instanceof HTMLInputElement)) {
|
|
87
229
|
return;
|
|
88
230
|
}
|
|
89
|
-
if (
|
|
90
|
-
|
|
231
|
+
if ($input.type === 'checkbox' || $input.type === 'radio') {
|
|
232
|
+
$input.checked = false;
|
|
91
233
|
} else {
|
|
92
|
-
|
|
234
|
+
$input.value = '';
|
|
93
235
|
}
|
|
94
236
|
});
|
|
95
237
|
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* @param {MouseEvent} event - Click event
|
|
241
|
+
*/
|
|
96
242
|
onRemoveButtonClick(event) {
|
|
97
|
-
const button = event.target;
|
|
98
|
-
if (
|
|
243
|
+
const $button = event.target;
|
|
244
|
+
if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__remove-button')) {
|
|
99
245
|
return;
|
|
100
246
|
}
|
|
101
|
-
button.closest('.moj-add-another__item').remove();
|
|
102
|
-
const items = this.getItems();
|
|
103
|
-
if (items.length === 1) {
|
|
104
|
-
items[0].querySelector('.moj-add-another__remove-button').remove();
|
|
247
|
+
$button.closest('.moj-add-another__item').remove();
|
|
248
|
+
const $items = this.getItems();
|
|
249
|
+
if ($items.length === 1) {
|
|
250
|
+
$items[0].querySelector('.moj-add-another__remove-button').remove();
|
|
105
251
|
}
|
|
106
|
-
items.forEach((
|
|
107
|
-
this.updateAttributes(
|
|
252
|
+
$items.forEach(($item, index) => {
|
|
253
|
+
this.updateAttributes($item, index);
|
|
108
254
|
});
|
|
109
255
|
this.focusHeading();
|
|
110
256
|
}
|
|
111
257
|
focusHeading() {
|
|
112
|
-
const heading = this.
|
|
113
|
-
if (heading && heading instanceof HTMLElement) {
|
|
114
|
-
heading.focus();
|
|
258
|
+
const $heading = this.$root.querySelector('.moj-add-another__heading');
|
|
259
|
+
if ($heading && $heading instanceof HTMLElement) {
|
|
260
|
+
$heading.focus();
|
|
115
261
|
}
|
|
116
262
|
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Name for the component used when initialising using data-module attributes.
|
|
266
|
+
*/
|
|
117
267
|
}
|
|
268
|
+
AddAnother.moduleName = 'moj-add-another';
|
|
118
269
|
|
|
119
270
|
export { AddAnother };
|
|
120
271
|
//# sourceMappingURL=add-another.bundle.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-another.bundle.mjs","sources":["../../../../src/moj/components/add-another/add-another.mjs"],"sourcesContent":["export class AddAnother {\n constructor(container) {\n this.container = container\n\n if (this.container.hasAttribute('data-moj-add-another-init')) {\n return this\n }\n\n this.container.setAttribute('data-moj-add-another-init', '')\n\n this.container.addEventListener(\n 'click',\n this.onRemoveButtonClick.bind(this)\n )\n this.container.addEventListener('click', this.onAddButtonClick.bind(this))\n\n const buttons = this.container.querySelectorAll(\n '.moj-add-another__add-button, moj-add-another__remove-button'\n )\n\n buttons.forEach((button) => {\n if (!(button instanceof HTMLButtonElement)) {\n return\n }\n\n button.type = 'button'\n })\n }\n\n onAddButtonClick(event) {\n const button = event.target\n\n if (\n !button ||\n !(button instanceof HTMLButtonElement) ||\n !button.classList.contains('moj-add-another__add-button')\n ) {\n return\n }\n\n const items = this.getItems()\n const item = this.getNewItem()\n\n if (!item || !(item instanceof HTMLElement)) {\n return\n }\n\n this.updateAttributes(item, items.length)\n this.resetItem(item)\n\n const firstItem = items[0]\n if (!this.hasRemoveButton(firstItem)) {\n this.createRemoveButton(firstItem)\n }\n\n items[items.length - 1].after(item)\n\n const input = item.querySelector('input, textarea, select')\n if (input && input instanceof HTMLInputElement) {\n input.focus()\n }\n }\n\n hasRemoveButton(item) {\n return item.querySelectorAll('.moj-add-another__remove-button').length\n }\n\n getItems() {\n if (!this.container) {\n return []\n }\n\n const items = Array.from(\n this.container.querySelectorAll('.moj-add-another__item')\n )\n\n return items.filter((item) => item instanceof HTMLElement)\n }\n\n getNewItem() {\n const items = this.getItems()\n const item = items[0].cloneNode(true)\n\n if (!item || !(item instanceof HTMLElement)) {\n return\n }\n\n if (!this.hasRemoveButton(item)) {\n this.createRemoveButton(item)\n }\n\n return item\n }\n\n updateAttributes(item, index) {\n item.querySelectorAll('[data-name]').forEach((el) => {\n if (!(el instanceof HTMLInputElement)) {\n return\n }\n\n const name = el.getAttribute('data-name') || ''\n const id = el.getAttribute('data-id') || ''\n const originalId = el.id\n\n el.name = name.replace(/%index%/, `${index}`)\n el.id = id.replace(/%index%/, `${index}`)\n\n const label =\n el.parentElement.querySelector('label') ||\n el.closest('label') ||\n item.querySelector(`[for=\"${originalId}\"]`)\n\n if (label && label instanceof HTMLLabelElement) {\n label.htmlFor = el.id\n }\n })\n }\n\n createRemoveButton(item) {\n const button = document.createElement('button')\n button.type = 'button'\n\n button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-add-another__remove-button'\n )\n\n button.textContent = 'Remove'\n\n item.append(button)\n }\n\n resetItem(item) {\n item.querySelectorAll('[data-name], [data-id]').forEach((el) => {\n if (!(el instanceof HTMLInputElement)) {\n return\n }\n\n if (el.type === 'checkbox' || el.type === 'radio') {\n el.checked = false\n } else {\n el.value = ''\n }\n })\n }\n\n onRemoveButtonClick(event) {\n const button = event.target\n\n if (\n !button ||\n !(button instanceof HTMLButtonElement) ||\n !button.classList.contains('moj-add-another__remove-button')\n ) {\n return\n }\n\n button.closest('.moj-add-another__item').remove()\n\n const items = this.getItems()\n\n if (items.length === 1) {\n items[0].querySelector('.moj-add-another__remove-button').remove()\n }\n\n items.forEach((el, index) => {\n this.updateAttributes(el, index)\n })\n\n this.focusHeading()\n }\n\n focusHeading() {\n const heading = this.container.querySelector('.moj-add-another__heading')\n\n if (heading && heading instanceof HTMLElement) {\n heading.focus()\n }\n }\n}\n"],"names":["AddAnother","constructor","container","hasAttribute","setAttribute","addEventListener","onRemoveButtonClick","bind","onAddButtonClick","buttons","querySelectorAll","forEach","button","HTMLButtonElement","type","event","target","classList","contains","items","getItems","item","getNewItem","HTMLElement","updateAttributes","length","resetItem","firstItem","hasRemoveButton","createRemoveButton","after","input","querySelector","HTMLInputElement","focus","Array","from","filter","cloneNode","index","el","name","getAttribute","id","originalId","replace","label","parentElement","closest","HTMLLabelElement","htmlFor","document","createElement","add","textContent","append","checked","value","remove","focusHeading","heading"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"add-another.bundle.mjs","sources":["../../../../node_modules/govuk-frontend/dist/govuk/common/index.mjs","../../../../node_modules/govuk-frontend/dist/govuk/errors/index.mjs","../../../../node_modules/govuk-frontend/dist/govuk/component.mjs","../../../../src/moj/components/add-another/add-another.mjs"],"sourcesContent":["function getFragmentFromUrl(url) {\n if (!url.includes('#')) {\n return undefined;\n }\n return url.split('#').pop();\n}\nfunction getBreakpoint(name) {\n const property = `--govuk-frontend-breakpoint-${name}`;\n const value = window.getComputedStyle(document.documentElement).getPropertyValue(property);\n return {\n property,\n value: value || undefined\n };\n}\nfunction setFocus($element, options = {}) {\n var _options$onBeforeFocu;\n const isFocusable = $element.getAttribute('tabindex');\n if (!isFocusable) {\n $element.setAttribute('tabindex', '-1');\n }\n function onFocus() {\n $element.addEventListener('blur', onBlur, {\n once: true\n });\n }\n function onBlur() {\n var _options$onBlur;\n (_options$onBlur = options.onBlur) == null || _options$onBlur.call($element);\n if (!isFocusable) {\n $element.removeAttribute('tabindex');\n }\n }\n $element.addEventListener('focus', onFocus, {\n once: true\n });\n (_options$onBeforeFocu = options.onBeforeFocus) == null || _options$onBeforeFocu.call($element);\n $element.focus();\n}\nfunction isInitialised($root, moduleName) {\n return $root instanceof HTMLElement && $root.hasAttribute(`data-${moduleName}-init`);\n}\n\n/**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * Some browsers will load and run our JavaScript but GOV.UK Frontend\n * won't be supported.\n *\n * @param {HTMLElement | null} [$scope] - (internal) `<body>` HTML element checked for browser support\n * @returns {boolean} Whether GOV.UK Frontend is supported on this page\n */\nfunction isSupported($scope = document.body) {\n if (!$scope) {\n return false;\n }\n return $scope.classList.contains('govuk-frontend-supported');\n}\nfunction isArray(option) {\n return Array.isArray(option);\n}\nfunction isObject(option) {\n return !!option && typeof option === 'object' && !isArray(option);\n}\nfunction formatErrorMessage(Component, message) {\n return `${Component.moduleName}: ${message}`;\n}\n/**\n * @typedef ComponentWithModuleName\n * @property {string} moduleName - Name of the component\n */\n/**\n * @import { ObjectNested } from './configuration.mjs'\n */\n\nexport { formatErrorMessage, getBreakpoint, getFragmentFromUrl, isInitialised, isObject, isSupported, setFocus };\n//# sourceMappingURL=index.mjs.map\n","import { formatErrorMessage } from '../common/index.mjs';\n\nclass GOVUKFrontendError extends Error {\n constructor(...args) {\n super(...args);\n this.name = 'GOVUKFrontendError';\n }\n}\nclass SupportError extends GOVUKFrontendError {\n /**\n * Checks if GOV.UK Frontend is supported on this page\n *\n * @param {HTMLElement | null} [$scope] - HTML element `<body>` checked for browser support\n */\n constructor($scope = document.body) {\n const supportMessage = 'noModule' in HTMLScriptElement.prototype ? 'GOV.UK Frontend initialised without `<body class=\"govuk-frontend-supported\">` from template `<script>` snippet' : 'GOV.UK Frontend is not supported in this browser';\n super($scope ? supportMessage : 'GOV.UK Frontend initialised without `<script type=\"module\">`');\n this.name = 'SupportError';\n }\n}\nclass ConfigError extends GOVUKFrontendError {\n constructor(...args) {\n super(...args);\n this.name = 'ConfigError';\n }\n}\nclass ElementError extends GOVUKFrontendError {\n constructor(messageOrOptions) {\n let message = typeof messageOrOptions === 'string' ? messageOrOptions : '';\n if (typeof messageOrOptions === 'object') {\n const {\n component,\n identifier,\n element,\n expectedType\n } = messageOrOptions;\n message = identifier;\n message += element ? ` is not of type ${expectedType != null ? expectedType : 'HTMLElement'}` : ' not found';\n message = formatErrorMessage(component, message);\n }\n super(message);\n this.name = 'ElementError';\n }\n}\nclass InitError extends GOVUKFrontendError {\n constructor(componentOrMessage) {\n const message = typeof componentOrMessage === 'string' ? componentOrMessage : formatErrorMessage(componentOrMessage, `Root element (\\`$root\\`) already initialised`);\n super(message);\n this.name = 'InitError';\n }\n}\n/**\n * @import { ComponentWithModuleName } from '../common/index.mjs'\n */\n\nexport { ConfigError, ElementError, GOVUKFrontendError, InitError, SupportError };\n//# sourceMappingURL=index.mjs.map\n","import { isInitialised, isSupported } from './common/index.mjs';\nimport { InitError, ElementError, SupportError } from './errors/index.mjs';\n\nclass Component {\n /**\n * Returns the root element of the component\n *\n * @protected\n * @returns {RootElementType} - the root element of component\n */\n get $root() {\n return this._$root;\n }\n constructor($root) {\n this._$root = void 0;\n const childConstructor = this.constructor;\n if (typeof childConstructor.moduleName !== 'string') {\n throw new InitError(`\\`moduleName\\` not defined in component`);\n }\n if (!($root instanceof childConstructor.elementType)) {\n throw new ElementError({\n element: $root,\n component: childConstructor,\n identifier: 'Root element (`$root`)',\n expectedType: childConstructor.elementType.name\n });\n } else {\n this._$root = $root;\n }\n childConstructor.checkSupport();\n this.checkInitialised();\n const moduleName = childConstructor.moduleName;\n this.$root.setAttribute(`data-${moduleName}-init`, '');\n }\n checkInitialised() {\n const constructor = this.constructor;\n const moduleName = constructor.moduleName;\n if (moduleName && isInitialised(this.$root, moduleName)) {\n throw new InitError(constructor);\n }\n }\n static checkSupport() {\n if (!isSupported()) {\n throw new SupportError();\n }\n }\n}\n\n/**\n * @typedef ChildClass\n * @property {string} moduleName - The module name that'll be looked for in the DOM when initialising the component\n */\n\n/**\n * @typedef {typeof Component & ChildClass} ChildClassConstructor\n */\nComponent.elementType = HTMLElement;\n\nexport { Component };\n//# sourceMappingURL=component.mjs.map\n","import { Component } from 'govuk-frontend'\n\nexport class AddAnother extends Component {\n /**\n * @param {Element | null} $root - HTML element to use for add another\n */\n constructor($root) {\n super($root)\n\n this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this))\n this.$root.addEventListener('click', this.onAddButtonClick.bind(this))\n\n const $buttons = this.$root.querySelectorAll(\n '.moj-add-another__add-button, moj-add-another__remove-button'\n )\n\n $buttons.forEach(($button) => {\n if (!($button instanceof HTMLButtonElement)) {\n return\n }\n\n $button.type = 'button'\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onAddButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__add-button')\n ) {\n return\n }\n\n const $items = this.getItems()\n const $item = this.getNewItem()\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n this.updateAttributes($item, $items.length)\n this.resetItem($item)\n\n const $firstItem = $items[0]\n if (!this.hasRemoveButton($firstItem)) {\n this.createRemoveButton($firstItem)\n }\n\n $items[$items.length - 1].after($item)\n\n const $input = $item.querySelector('input, textarea, select')\n if ($input && $input instanceof HTMLInputElement) {\n $input.focus()\n }\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n hasRemoveButton($item) {\n return $item.querySelectorAll('.moj-add-another__remove-button').length\n }\n\n getItems() {\n if (!this.$root) {\n return []\n }\n\n const $items = Array.from(\n this.$root.querySelectorAll('.moj-add-another__item')\n )\n\n return $items.filter((item) => item instanceof HTMLElement)\n }\n\n getNewItem() {\n const $items = this.getItems()\n const $item = $items[0].cloneNode(true)\n\n if (!$item || !($item instanceof HTMLElement)) {\n return\n }\n\n if (!this.hasRemoveButton($item)) {\n this.createRemoveButton($item)\n }\n\n return $item\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n * @param {number} index - Add another item index\n */\n updateAttributes($item, index) {\n $item.querySelectorAll('[data-name]').forEach(($input) => {\n if (!($input instanceof HTMLInputElement)) {\n return\n }\n\n const name = $input.getAttribute('data-name') || ''\n const id = $input.getAttribute('data-id') || ''\n const originalId = $input.id\n\n $input.name = name.replace(/%index%/, `${index}`)\n $input.id = id.replace(/%index%/, `${index}`)\n\n const $label =\n $input.parentElement.querySelector('label') ||\n $input.closest('label') ||\n $item.querySelector(`[for=\"${originalId}\"]`)\n\n if ($label && $label instanceof HTMLLabelElement) {\n $label.htmlFor = $input.id\n }\n })\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n createRemoveButton($item) {\n const $button = document.createElement('button')\n $button.type = 'button'\n\n $button.classList.add(\n 'govuk-button',\n 'govuk-button--secondary',\n 'moj-add-another__remove-button'\n )\n\n $button.textContent = 'Remove'\n\n $item.append($button)\n }\n\n /**\n * @param {HTMLElement} $item - Add another item\n */\n resetItem($item) {\n $item.querySelectorAll('[data-name], [data-id]').forEach(($input) => {\n if (!($input instanceof HTMLInputElement)) {\n return\n }\n\n if ($input.type === 'checkbox' || $input.type === 'radio') {\n $input.checked = false\n } else {\n $input.value = ''\n }\n })\n }\n\n /**\n * @param {MouseEvent} event - Click event\n */\n onRemoveButtonClick(event) {\n const $button = event.target\n\n if (\n !$button ||\n !($button instanceof HTMLButtonElement) ||\n !$button.classList.contains('moj-add-another__remove-button')\n ) {\n return\n }\n\n $button.closest('.moj-add-another__item').remove()\n\n const $items = this.getItems()\n\n if ($items.length === 1) {\n $items[0].querySelector('.moj-add-another__remove-button').remove()\n }\n\n $items.forEach(($item, index) => {\n this.updateAttributes($item, index)\n })\n\n this.focusHeading()\n }\n\n focusHeading() {\n const $heading = this.$root.querySelector('.moj-add-another__heading')\n\n if ($heading && $heading instanceof HTMLElement) {\n $heading.focus()\n }\n }\n\n /**\n * Name for the component used when initialising using data-module attributes.\n */\n static moduleName = 'moj-add-another'\n}\n"],"names":["isInitialised","$root","moduleName","HTMLElement","hasAttribute","isSupported","$scope","document","body","classList","contains","formatErrorMessage","Component","message","GOVUKFrontendError","Error","constructor","args","name","SupportError","supportMessage","HTMLScriptElement","prototype","ElementError","messageOrOptions","component","identifier","element","expectedType","InitError","componentOrMessage","_$root","childConstructor","elementType","checkSupport","checkInitialised","setAttribute","AddAnother","addEventListener","onRemoveButtonClick","bind","onAddButtonClick","$buttons","querySelectorAll","forEach","$button","HTMLButtonElement","type","event","target","$items","getItems","$item","getNewItem","updateAttributes","length","resetItem","$firstItem","hasRemoveButton","createRemoveButton","after","$input","querySelector","HTMLInputElement","focus","Array","from","filter","item","cloneNode","index","getAttribute","id","originalId","replace","$label","parentElement","closest","HTMLLabelElement","htmlFor","createElement","add","textContent","append","checked","value","remove","focusHeading","$heading"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
@@ -1,120 +1,151 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.
|
|
10
|
-
|
|
11
|
-
buttons.
|
|
12
|
-
|
|
1
|
+
import { Component } from 'govuk-frontend';
|
|
2
|
+
|
|
3
|
+
class AddAnother extends Component {
|
|
4
|
+
/**
|
|
5
|
+
* @param {Element | null} $root - HTML element to use for add another
|
|
6
|
+
*/
|
|
7
|
+
constructor($root) {
|
|
8
|
+
super($root);
|
|
9
|
+
this.$root.addEventListener('click', this.onRemoveButtonClick.bind(this));
|
|
10
|
+
this.$root.addEventListener('click', this.onAddButtonClick.bind(this));
|
|
11
|
+
const $buttons = this.$root.querySelectorAll('.moj-add-another__add-button, moj-add-another__remove-button');
|
|
12
|
+
$buttons.forEach($button => {
|
|
13
|
+
if (!($button instanceof HTMLButtonElement)) {
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
|
-
button.type = 'button';
|
|
16
|
+
$button.type = 'button';
|
|
16
17
|
});
|
|
17
18
|
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {MouseEvent} event - Click event
|
|
22
|
+
*/
|
|
18
23
|
onAddButtonClick(event) {
|
|
19
|
-
const button = event.target;
|
|
20
|
-
if (
|
|
24
|
+
const $button = event.target;
|
|
25
|
+
if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__add-button')) {
|
|
21
26
|
return;
|
|
22
27
|
}
|
|
23
|
-
const items = this.getItems();
|
|
24
|
-
const item = this.getNewItem();
|
|
25
|
-
if (
|
|
28
|
+
const $items = this.getItems();
|
|
29
|
+
const $item = this.getNewItem();
|
|
30
|
+
if (!$item || !($item instanceof HTMLElement)) {
|
|
26
31
|
return;
|
|
27
32
|
}
|
|
28
|
-
this.updateAttributes(item, items.length);
|
|
29
|
-
this.resetItem(item);
|
|
30
|
-
const firstItem = items[0];
|
|
31
|
-
if (!this.hasRemoveButton(firstItem)) {
|
|
32
|
-
this.createRemoveButton(firstItem);
|
|
33
|
+
this.updateAttributes($item, $items.length);
|
|
34
|
+
this.resetItem($item);
|
|
35
|
+
const $firstItem = $items[0];
|
|
36
|
+
if (!this.hasRemoveButton($firstItem)) {
|
|
37
|
+
this.createRemoveButton($firstItem);
|
|
33
38
|
}
|
|
34
|
-
items[items.length - 1].after(item);
|
|
35
|
-
const input = item.querySelector('input, textarea, select');
|
|
36
|
-
if (input && input instanceof HTMLInputElement) {
|
|
37
|
-
input.focus();
|
|
39
|
+
$items[$items.length - 1].after($item);
|
|
40
|
+
const $input = $item.querySelector('input, textarea, select');
|
|
41
|
+
if ($input && $input instanceof HTMLInputElement) {
|
|
42
|
+
$input.focus();
|
|
38
43
|
}
|
|
39
44
|
}
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {HTMLElement} $item - Add another item
|
|
48
|
+
*/
|
|
49
|
+
hasRemoveButton($item) {
|
|
50
|
+
return $item.querySelectorAll('.moj-add-another__remove-button').length;
|
|
42
51
|
}
|
|
43
52
|
getItems() {
|
|
44
|
-
if (!this
|
|
53
|
+
if (!this.$root) {
|
|
45
54
|
return [];
|
|
46
55
|
}
|
|
47
|
-
const items = Array.from(this.
|
|
48
|
-
return items.filter(item => item instanceof HTMLElement);
|
|
56
|
+
const $items = Array.from(this.$root.querySelectorAll('.moj-add-another__item'));
|
|
57
|
+
return $items.filter(item => item instanceof HTMLElement);
|
|
49
58
|
}
|
|
50
59
|
getNewItem() {
|
|
51
|
-
const items = this.getItems();
|
|
52
|
-
const item = items[0].cloneNode(true);
|
|
53
|
-
if (
|
|
60
|
+
const $items = this.getItems();
|
|
61
|
+
const $item = $items[0].cloneNode(true);
|
|
62
|
+
if (!$item || !($item instanceof HTMLElement)) {
|
|
54
63
|
return;
|
|
55
64
|
}
|
|
56
|
-
if (!this.hasRemoveButton(item)) {
|
|
57
|
-
this.createRemoveButton(item);
|
|
65
|
+
if (!this.hasRemoveButton($item)) {
|
|
66
|
+
this.createRemoveButton($item);
|
|
58
67
|
}
|
|
59
|
-
return item;
|
|
68
|
+
return $item;
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {HTMLElement} $item - Add another item
|
|
73
|
+
* @param {number} index - Add another item index
|
|
74
|
+
*/
|
|
75
|
+
updateAttributes($item, index) {
|
|
76
|
+
$item.querySelectorAll('[data-name]').forEach($input => {
|
|
77
|
+
if (!($input instanceof HTMLInputElement)) {
|
|
64
78
|
return;
|
|
65
79
|
}
|
|
66
|
-
const name =
|
|
67
|
-
const id =
|
|
68
|
-
const originalId =
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const label =
|
|
72
|
-
if (label && label instanceof HTMLLabelElement) {
|
|
73
|
-
label.htmlFor =
|
|
80
|
+
const name = $input.getAttribute('data-name') || '';
|
|
81
|
+
const id = $input.getAttribute('data-id') || '';
|
|
82
|
+
const originalId = $input.id;
|
|
83
|
+
$input.name = name.replace(/%index%/, `${index}`);
|
|
84
|
+
$input.id = id.replace(/%index%/, `${index}`);
|
|
85
|
+
const $label = $input.parentElement.querySelector('label') || $input.closest('label') || $item.querySelector(`[for="${originalId}"]`);
|
|
86
|
+
if ($label && $label instanceof HTMLLabelElement) {
|
|
87
|
+
$label.htmlFor = $input.id;
|
|
74
88
|
}
|
|
75
89
|
});
|
|
76
90
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* @param {HTMLElement} $item - Add another item
|
|
94
|
+
*/
|
|
95
|
+
createRemoveButton($item) {
|
|
96
|
+
const $button = document.createElement('button');
|
|
97
|
+
$button.type = 'button';
|
|
98
|
+
$button.classList.add('govuk-button', 'govuk-button--secondary', 'moj-add-another__remove-button');
|
|
99
|
+
$button.textContent = 'Remove';
|
|
100
|
+
$item.append($button);
|
|
83
101
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {HTMLElement} $item - Add another item
|
|
105
|
+
*/
|
|
106
|
+
resetItem($item) {
|
|
107
|
+
$item.querySelectorAll('[data-name], [data-id]').forEach($input => {
|
|
108
|
+
if (!($input instanceof HTMLInputElement)) {
|
|
87
109
|
return;
|
|
88
110
|
}
|
|
89
|
-
if (
|
|
90
|
-
|
|
111
|
+
if ($input.type === 'checkbox' || $input.type === 'radio') {
|
|
112
|
+
$input.checked = false;
|
|
91
113
|
} else {
|
|
92
|
-
|
|
114
|
+
$input.value = '';
|
|
93
115
|
}
|
|
94
116
|
});
|
|
95
117
|
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @param {MouseEvent} event - Click event
|
|
121
|
+
*/
|
|
96
122
|
onRemoveButtonClick(event) {
|
|
97
|
-
const button = event.target;
|
|
98
|
-
if (
|
|
123
|
+
const $button = event.target;
|
|
124
|
+
if (!$button || !($button instanceof HTMLButtonElement) || !$button.classList.contains('moj-add-another__remove-button')) {
|
|
99
125
|
return;
|
|
100
126
|
}
|
|
101
|
-
button.closest('.moj-add-another__item').remove();
|
|
102
|
-
const items = this.getItems();
|
|
103
|
-
if (items.length === 1) {
|
|
104
|
-
items[0].querySelector('.moj-add-another__remove-button').remove();
|
|
127
|
+
$button.closest('.moj-add-another__item').remove();
|
|
128
|
+
const $items = this.getItems();
|
|
129
|
+
if ($items.length === 1) {
|
|
130
|
+
$items[0].querySelector('.moj-add-another__remove-button').remove();
|
|
105
131
|
}
|
|
106
|
-
items.forEach((
|
|
107
|
-
this.updateAttributes(
|
|
132
|
+
$items.forEach(($item, index) => {
|
|
133
|
+
this.updateAttributes($item, index);
|
|
108
134
|
});
|
|
109
135
|
this.focusHeading();
|
|
110
136
|
}
|
|
111
137
|
focusHeading() {
|
|
112
|
-
const heading = this.
|
|
113
|
-
if (heading && heading instanceof HTMLElement) {
|
|
114
|
-
heading.focus();
|
|
138
|
+
const $heading = this.$root.querySelector('.moj-add-another__heading');
|
|
139
|
+
if ($heading && $heading instanceof HTMLElement) {
|
|
140
|
+
$heading.focus();
|
|
115
141
|
}
|
|
116
142
|
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Name for the component used when initialising using data-module attributes.
|
|
146
|
+
*/
|
|
117
147
|
}
|
|
148
|
+
AddAnother.moduleName = 'moj-add-another';
|
|
118
149
|
|
|
119
150
|
export { AddAnother };
|
|
120
151
|
//# sourceMappingURL=add-another.mjs.map
|