1 | import $ from './jquery';
|
2 | import amdify from './internal/amdify';
|
3 | import skate from './internal/skate';
|
4 | import './spinner'
|
5 | import {getMessageLogger} from './internal/deprecation'
|
6 |
|
7 | const CLASS_NOTIFICATION_INITIALISED = '_aui-form-notification-initialised';
|
8 |
|
9 | const ATTRIBUTE_NOTIFICATION_PREFIX = 'data-aui-notification-';
|
10 | const ATTRIBUTE_NOTIFICATION_WAIT = ATTRIBUTE_NOTIFICATION_PREFIX + 'wait';
|
11 | const ATTRIBUTE_NOTIFICATION_INFO = ATTRIBUTE_NOTIFICATION_PREFIX + 'info';
|
12 | const ATTRIBUTE_NOTIFICATION_ERROR = ATTRIBUTE_NOTIFICATION_PREFIX + 'error';
|
13 | const ATTRIBUTE_NOTIFICATION_SUCCESS = ATTRIBUTE_NOTIFICATION_PREFIX + 'success';
|
14 |
|
15 | const NOTIFICATION_PRIORITY = [
|
16 | ATTRIBUTE_NOTIFICATION_ERROR,
|
17 | ATTRIBUTE_NOTIFICATION_SUCCESS,
|
18 | ATTRIBUTE_NOTIFICATION_WAIT,
|
19 | ATTRIBUTE_NOTIFICATION_INFO
|
20 | ];
|
21 |
|
22 | function initialiseNotification($field) {
|
23 | if (!isFieldInitialised($field)) {
|
24 | prepareFieldMarkup($field);
|
25 | synchroniseNotificationDisplay($field);
|
26 | }
|
27 | }
|
28 |
|
29 | function isFieldInitialised($field) {
|
30 | return $field.hasClass(CLASS_NOTIFICATION_INITIALISED);
|
31 | }
|
32 |
|
33 | function prepareFieldMarkup($field) {
|
34 | $field.addClass(CLASS_NOTIFICATION_INITIALISED);
|
35 | appendDescription($field);
|
36 | }
|
37 |
|
38 | function appendDescription($field, message) {
|
39 | message = message ? message : getNotificationMessage($field);
|
40 | if (getFieldNotificationType($field) === ATTRIBUTE_NOTIFICATION_INFO) {
|
41 | $field.after(descriptionTemplate(message))
|
42 | }
|
43 | }
|
44 |
|
45 | function getNotificationMessage($field) {
|
46 | var notificationType = getFieldNotificationType($field);
|
47 | var message = notificationType ? $field.attr(notificationType) : '';
|
48 | return message === '' ? message : jsonToArray(message);
|
49 | }
|
50 |
|
51 | function jsonToArray(jsonOrString) {
|
52 | var jsonArray;
|
53 | try {
|
54 | jsonArray = JSON.parse(jsonOrString);
|
55 | } catch (exception) {
|
56 | jsonArray = [jsonOrString];
|
57 | }
|
58 | return jsonArray;
|
59 | }
|
60 |
|
61 | function getFieldNotificationType($field) {
|
62 | var fieldNotificationType;
|
63 | NOTIFICATION_PRIORITY.some(function (prioritisedNotification) {
|
64 | if ($field.is('[' + prioritisedNotification + ']')) {
|
65 | fieldNotificationType = prioritisedNotification;
|
66 | return true;
|
67 | }
|
68 | });
|
69 |
|
70 | return fieldNotificationType;
|
71 | }
|
72 |
|
73 | function synchroniseNotificationDisplay(field) {
|
74 | const $field = $(field);
|
75 |
|
76 | if (!isFieldInitialised($field)) {
|
77 | return;
|
78 | }
|
79 | const type = getFieldNotificationType($field);
|
80 | const showSpinner = type === ATTRIBUTE_NOTIFICATION_WAIT;
|
81 |
|
82 | setFieldSpinner($field, showSpinner);
|
83 |
|
84 | const message = getNotificationMessage($field);
|
85 | if (message && type === ATTRIBUTE_NOTIFICATION_ERROR) {
|
86 | appendErrorMessages($field, message);
|
87 | return;
|
88 | }
|
89 |
|
90 |
|
91 |
|
92 | if (!isJqueryObject(field) && !field.hasAttribute(ATTRIBUTE_NOTIFICATION_ERROR)) {
|
93 | $field.parent().find('.error').remove();
|
94 | }
|
95 | }
|
96 |
|
97 | function isJqueryObject(el) {
|
98 | return el.constructor.prototype.hasOwnProperty('jquery');
|
99 | }
|
100 |
|
101 | function errorMessageTemplate(messages) {
|
102 | let list = messages
|
103 | .map(message => `<li><span class="aui-icon aui-icon-small aui-iconfont-error aui-icon-notification">${message}</span>${message}</li>`)
|
104 | .join('');
|
105 | return `<div class="error"><ul>${list}</ul></div>`;
|
106 | }
|
107 |
|
108 | function descriptionTemplate(messages) {
|
109 | if (messages.length > 1) {
|
110 | let list = messages
|
111 | .map(message => `<li>${message}</li>`)
|
112 | .join('');
|
113 | return `<div class="description"><ul>${list}</ul></div>`;
|
114 | }
|
115 | return `<div class="description">${messages}</div>`;
|
116 | }
|
117 |
|
118 | function appendErrorMessages($field, messages) {
|
119 | let previousErrors = getMessageContainer($field, 'error');
|
120 | if (previousErrors.length > 0) {
|
121 | previousErrors.remove();
|
122 | }
|
123 | $field.after(errorMessageTemplate(messages));
|
124 | }
|
125 |
|
126 | function getMessageContainer($field, type) {
|
127 | return $field.parent().find(`.${type}`);
|
128 | }
|
129 |
|
130 | function isSpinnerForFieldAlreadyExisting($field) {
|
131 | return $field.next('aui-spinner').length > 0;
|
132 | }
|
133 |
|
134 | function setFieldSpinner($field, isSpinnerVisible) {
|
135 | if (isSpinnerVisible && !isSpinnerForFieldAlreadyExisting($field)) {
|
136 | $field.after('<aui-spinner class="form-notification-spinner" size="small"></aui-spinner>');
|
137 | } else {
|
138 | $field.parent().find('aui-spinner').remove();
|
139 | }
|
140 | }
|
141 |
|
142 | const deprecationLogger = getMessageLogger('data-aui-notification-field attribute', {
|
143 | deprecationType: 'ATTRIBUTE',
|
144 | alternativeName: 'HTML markup'
|
145 | });
|
146 |
|
147 | skate('data-aui-notification-field', {
|
148 | attached: function (element) {
|
149 | deprecationLogger();
|
150 | initialiseNotification($(element));
|
151 | },
|
152 | attributes: (function () {
|
153 | const attrs = {};
|
154 | NOTIFICATION_PRIORITY.forEach(function (type) {
|
155 | attrs[type] = synchroniseNotificationDisplay;
|
156 | });
|
157 | return attrs;
|
158 | }()),
|
159 | type: skate.type.ATTRIBUTE
|
160 | });
|
161 |
|
162 | amdify('aui/form-notification');
|
163 |
|
164 | export {
|
165 | getMessageContainer,
|
166 | appendErrorMessages,
|
167 | appendDescription,
|
168 | errorMessageTemplate,
|
169 | setFieldSpinner
|
170 | }
|