UNPKG

@atlassian/aui

Version:

Atlassian User Interface library

171 lines (143 loc) 5.2 kB
import $ from './jquery'; import amdify from './internal/amdify'; import skate from './internal/skate'; import './spinner' import {getMessageLogger} from './internal/deprecation' const CLASS_NOTIFICATION_INITIALISED = '_aui-form-notification-initialised'; const ATTRIBUTE_NOTIFICATION_PREFIX = 'data-aui-notification-'; const ATTRIBUTE_NOTIFICATION_WAIT = ATTRIBUTE_NOTIFICATION_PREFIX + 'wait'; const ATTRIBUTE_NOTIFICATION_INFO = ATTRIBUTE_NOTIFICATION_PREFIX + 'info'; const ATTRIBUTE_NOTIFICATION_ERROR = ATTRIBUTE_NOTIFICATION_PREFIX + 'error'; const ATTRIBUTE_NOTIFICATION_SUCCESS = ATTRIBUTE_NOTIFICATION_PREFIX + 'success'; const NOTIFICATION_PRIORITY = [ ATTRIBUTE_NOTIFICATION_ERROR, ATTRIBUTE_NOTIFICATION_SUCCESS, ATTRIBUTE_NOTIFICATION_WAIT, ATTRIBUTE_NOTIFICATION_INFO ]; function initialiseNotification($field) { if (!isFieldInitialised($field)) { prepareFieldMarkup($field); synchroniseNotificationDisplay($field); } } function isFieldInitialised($field) { return $field.hasClass(CLASS_NOTIFICATION_INITIALISED); } function prepareFieldMarkup($field) { $field.addClass(CLASS_NOTIFICATION_INITIALISED); appendDescription($field); } function appendDescription($field, message) { message = message ? message : getNotificationMessage($field); if (getFieldNotificationType($field) === ATTRIBUTE_NOTIFICATION_INFO) { $field.after(descriptionTemplate(message)) } } function getNotificationMessage($field) { var notificationType = getFieldNotificationType($field); var message = notificationType ? $field.attr(notificationType) : ''; return message === '' ? message : jsonToArray(message); } function jsonToArray(jsonOrString) { var jsonArray; try { jsonArray = JSON.parse(jsonOrString); } catch (exception) { jsonArray = [jsonOrString]; } return jsonArray; } function getFieldNotificationType($field) { var fieldNotificationType; NOTIFICATION_PRIORITY.some(function (prioritisedNotification) { if ($field.is('[' + prioritisedNotification + ']')) { fieldNotificationType = prioritisedNotification; return true; } }); return fieldNotificationType; } function synchroniseNotificationDisplay(field) { const $field = $(field); if (!isFieldInitialised($field)) { return; } const type = getFieldNotificationType($field); const showSpinner = type === ATTRIBUTE_NOTIFICATION_WAIT; setFieldSpinner($field, showSpinner); const message = getNotificationMessage($field); if (message && type === ATTRIBUTE_NOTIFICATION_ERROR) { appendErrorMessages($field, message); return; } // the first call of this method is executed on init with jQuery wrapped object // subsequent ones are the ones we care about and those are executed with DOM objects if (!isJqueryObject(field) && !field.hasAttribute(ATTRIBUTE_NOTIFICATION_ERROR)) { $field.parent().find('.error').remove(); } } function isJqueryObject(el) { return el.constructor.prototype.hasOwnProperty('jquery'); } function errorMessageTemplate(messages) { let list = messages .map(message => `<li><span class="aui-icon aui-icon-small aui-iconfont-error aui-icon-notification">${message}</span>${message}</li>`) .join(''); return `<div class="error"><ul>${list}</ul></div>`; } function descriptionTemplate(messages) { if (messages.length > 1) { let list = messages .map(message => `<li>${message}</li>`) .join(''); return `<div class="description"><ul>${list}</ul></div>`; } return `<div class="description">${messages}</div>`; } function appendErrorMessages($field, messages) { let previousErrors = getMessageContainer($field, 'error'); if (previousErrors.length > 0) { previousErrors.remove(); } $field.after(errorMessageTemplate(messages)); } function getMessageContainer($field, type) { return $field.parent().find(`.${type}`); } function isSpinnerForFieldAlreadyExisting($field) { return $field.next('aui-spinner').length > 0; } function setFieldSpinner($field, isSpinnerVisible) { if (isSpinnerVisible && !isSpinnerForFieldAlreadyExisting($field)) { $field.after('<aui-spinner class="form-notification-spinner" size="small"></aui-spinner>'); } else { $field.parent().find('aui-spinner').remove(); } } const deprecationLogger = getMessageLogger('data-aui-notification-field attribute', { deprecationType: 'ATTRIBUTE', alternativeName: 'HTML markup' }); skate('data-aui-notification-field', { attached: function (element) { deprecationLogger(); initialiseNotification($(element)); }, attributes: (function () { const attrs = {}; NOTIFICATION_PRIORITY.forEach(function (type) { attrs[type] = synchroniseNotificationDisplay; }); return attrs; }()), type: skate.type.ATTRIBUTE }); amdify('aui/form-notification'); export { getMessageContainer, appendErrorMessages, appendDescription, errorMessageTemplate, setFieldSpinner }