@atlassian/aui
Version:
Atlassian User Interface library
171 lines (143 loc) • 5.2 kB
JavaScript
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
}