UNPKG

5.2 kBJavaScriptView Raw
1import $ from './jquery';
2import amdify from './internal/amdify';
3import skate from './internal/skate';
4import './spinner'
5import {getMessageLogger} from './internal/deprecation'
6
7const CLASS_NOTIFICATION_INITIALISED = '_aui-form-notification-initialised';
8
9const ATTRIBUTE_NOTIFICATION_PREFIX = 'data-aui-notification-';
10const ATTRIBUTE_NOTIFICATION_WAIT = ATTRIBUTE_NOTIFICATION_PREFIX + 'wait';
11const ATTRIBUTE_NOTIFICATION_INFO = ATTRIBUTE_NOTIFICATION_PREFIX + 'info';
12const ATTRIBUTE_NOTIFICATION_ERROR = ATTRIBUTE_NOTIFICATION_PREFIX + 'error';
13const ATTRIBUTE_NOTIFICATION_SUCCESS = ATTRIBUTE_NOTIFICATION_PREFIX + 'success';
14
15const NOTIFICATION_PRIORITY = [
16 ATTRIBUTE_NOTIFICATION_ERROR,
17 ATTRIBUTE_NOTIFICATION_SUCCESS,
18 ATTRIBUTE_NOTIFICATION_WAIT,
19 ATTRIBUTE_NOTIFICATION_INFO
20];
21
22function initialiseNotification($field) {
23 if (!isFieldInitialised($field)) {
24 prepareFieldMarkup($field);
25 synchroniseNotificationDisplay($field);
26 }
27}
28
29function isFieldInitialised($field) {
30 return $field.hasClass(CLASS_NOTIFICATION_INITIALISED);
31}
32
33function prepareFieldMarkup($field) {
34 $field.addClass(CLASS_NOTIFICATION_INITIALISED);
35 appendDescription($field);
36}
37
38function appendDescription($field, message) {
39 message = message ? message : getNotificationMessage($field);
40 if (getFieldNotificationType($field) === ATTRIBUTE_NOTIFICATION_INFO) {
41 $field.after(descriptionTemplate(message))
42 }
43}
44
45function getNotificationMessage($field) {
46 var notificationType = getFieldNotificationType($field);
47 var message = notificationType ? $field.attr(notificationType) : '';
48 return message === '' ? message : jsonToArray(message);
49}
50
51function jsonToArray(jsonOrString) {
52 var jsonArray;
53 try {
54 jsonArray = JSON.parse(jsonOrString);
55 } catch (exception) {
56 jsonArray = [jsonOrString];
57 }
58 return jsonArray;
59}
60
61function 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
73function 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 // the first call of this method is executed on init with jQuery wrapped object
91 // subsequent ones are the ones we care about and those are executed with DOM objects
92 if (!isJqueryObject(field) && !field.hasAttribute(ATTRIBUTE_NOTIFICATION_ERROR)) {
93 $field.parent().find('.error').remove();
94 }
95}
96
97function isJqueryObject(el) {
98 return el.constructor.prototype.hasOwnProperty('jquery');
99}
100
101function 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
108function 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
118function 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
126function getMessageContainer($field, type) {
127 return $field.parent().find(`.${type}`);
128}
129
130function isSpinnerForFieldAlreadyExisting($field) {
131 return $field.next('aui-spinner').length > 0;
132}
133
134function 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
142const deprecationLogger = getMessageLogger('data-aui-notification-field attribute', {
143 deprecationType: 'ATTRIBUTE',
144 alternativeName: 'HTML markup'
145});
146
147skate('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
162amdify('aui/form-notification');
163
164export {
165 getMessageContainer,
166 appendErrorMessages,
167 appendDescription,
168 errorMessageTemplate,
169 setFieldSpinner
170}