breezy_utility-1.0.x-dev/js/breezy_utility.ajax.js
js/breezy_utility.ajax.js
/**
* @file
* JavaScript behaviors for Ajax.
*/
(($, Drupal, drupalSettings, once) => {
/**
* Close dialogs.
*/
function closeDialogs() {
const $dialogs = $('.ui-dialog:visible').find('.ui-dialog-content');
if ($dialogs.length) {
$dialogs.each(($index, $element) => {
if (typeof $.fn.dialog === 'function') {
$($element).dialog('close');
}
});
}
}
/**
* Provides Breezy Ajax link behavior.
*/
Drupal.behaviors.breezyAjaxLink = {
attach(context) {
$(once('breezy-ajax-link', '.breezy-ajax-link', context)).each(
($index, $element) => {
const $elementSettings = {};
$elementSettings.progress = { type: 'fullscreen' };
const $href = $($element).attr('href');
if ($href) {
$elementSettings.url = $href;
$elementSettings.event = 'click';
}
$elementSettings.dialogType = $($element).data('dialog-type');
$elementSettings.dialogRenderer = $($element).data('dialog-renderer');
$elementSettings.dialog = $($element).data('dialog-options');
$elementSettings.base = $($element).attr('id');
$elementSettings.element = $element;
Drupal.ajax($elementSettings);
if ($elementSettings.dialogRenderer === 'off_canvas') {
$($element).on('click', () => {
closeDialogs();
});
}
},
);
},
};
/**
* Track the updated table row key.
*/
let updateKey;
/**
* Track the add element key.
*/
let addElement;
/**
* Command to insert new content into the DOM.
*
* @param {Drupal.Ajax} ajax
* {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
* @param {object} response
* The response from the Ajax request.
* @param {string} response.data
* The data to use with the jQuery method.
* @param {string} [response.method]
* The jQuery DOM manipulation method to be used.
* @param {string} [response.selector]
* A optional jQuery selector string.
* @param {object} [response.settings]
* An optional array of settings that will be used.
* @param {number} [status]
* The XMLHttpRequest status.
*/
Drupal.AjaxCommands.prototype.breezyInsert = (ajax, response, status) => {
// Insert the HTML.
Drupal.AjaxCommands.prototype.insert(ajax, response, status);
// Add element.
if (addElement) {
const addSelector =
addElement === '_root_'
? '#breezy-ui-add-element'
: `'[data-drupal-selector="edit-breezy-ui-elements-' ${addElement} '-add"]'`;
$(addSelector).trigger('click');
}
// If not add element, then scroll to and highlight the updated table row.
if (!addElement && updateKey) {
const $element = $(`tr[data-breezy-key="${updateKey}"]`);
// Highlight the updated element's row.
$element.addClass('color-success');
setTimeout(() => {
$element.removeClass('color-success');
}, 3000);
// Focus first tabbable item for the updated elements and handlers.
$element.find(':tabbable:not(.tabledrag-handle)').eq(0).trigger('focus');
// Scroll element into view.
// Drupal.breezyScrolledIntoView($element);.
} else {
// Focus main content.
$('#main-content').trigger('focus');
}
// Display main page's status message in a floating container.
const $wrapper = $(response.selector);
if ($wrapper.parents('.ui-dialog').length === 0) {
const $messages = $wrapper.find('.messages');
// If 'add element' don't show any messages.
if (addElement) {
$messages.remove();
} else if ($messages.length) {
let $floatingMessage = $('#breezy-ajax-messages');
if ($floatingMessage.length === 0) {
$floatingMessage = $(
'<div id="breezy-ajax-messages" class="breezy-ajax-messages"></div>',
);
$('body').append($floatingMessage);
}
// eslint-disable-next-line jquery/no-is
if ($floatingMessage.is(':animated')) {
$floatingMessage.stop(true, true);
}
$floatingMessage.html($messages).show().delay(3000).fadeOut(1000);
}
}
updateKey = null; // Reset element update.
addElement = null; // Reset add element.
};
/**
* Scroll to top ajax command.
*
* @param {Drupal.Ajax} [ajax]
* A {@link Drupal.ajax} object.
* @param {object} response
* Ajax response.
* @param {string} response.selector
* Selector to use.
*
* @see Drupal.AjaxCommands.prototype.viewScrollTop
*/
Drupal.AjaxCommands.prototype.breezyScrollTop = (ajax, response) => {
// Scroll top.
Drupal.breezyScrollTop(response.selector, response.target);
// Focus on the form wrapper content bookmark if
// .js-breezy-autofocus is not enabled.
// @see \Drupal\breezy_utility\Form\BreezyUtilityAjaxFormTrait::buildAjaxForm
const $form = $(`${response.selector}-content`).find('form');
if (!$form.hasClass('js-breezy-autofocus')) {
$(`${response.selector}-content`).trigger('focus');
}
};
/**
* Command to refresh the current Breezy page.
*
* @param {Drupal.Ajax} [ajax]
* {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
* @param {object} response
* The response from the Ajax request.
* @param {string} response.url
* The URL to redirect to.
* @param {number} [status]
* The XMLHttpRequest status.
*/
Drupal.AjaxCommands.prototype.breezyRefresh = (ajax, response, status) => {
// Get URL path name.
// @see https://stackoverflow.com/questions/6944744/javascript-get-portion-of-url-path
const a = document.createElement('a');
a.href = response.url;
const forceReload = response.url.match(/\?reload=([^&]+)($|&)/)
? RegExp.$1
: null;
if (forceReload) {
response.url = response.url.replace(/\?reload=([^&]+)($|&)/, '');
Drupal.AjaxCommands.prototype.redirect(ajax, response, status);
return;
}
if (
a.pathname === window.location.pathname &&
$('.breezy-ajax-refresh').length
) {
updateKey = response.url.match(/[?|&]update=([^&]+)($|&)/)
? RegExp.$1
: null;
addElement = response.url.match(/[?|&]add_element=([^&]+)($|&)/)
? RegExp.$1
: null;
$('.breezy-ajax-refresh').trigger('click');
} else {
// Clear unsaved information flag so that the current Breezy page
// can be redirected.
// @see Drupal.behaviors.breezyUnsaved.clear
if (Drupal.behaviors.breezyUnsaved) {
Drupal.behaviors.breezyUnsaved.clear();
}
Drupal.AjaxCommands.prototype.redirect(ajax, response, status);
}
};
/**
* Command to close a off-canvas and modal dialog.
*
* If no selector is given, it defaults to trying to close the modal.
*
* @param {Drupal.Ajax} [ajax]
* {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
* @param {object} response
* The response from the Ajax request.
* @param {string} response.selector
* Selector to use.
* @param {bool} response.persist
* Whether to persist the dialog element or not.
* @param {number} [status]
* The HTTP status code.
*/
Drupal.AjaxCommands.prototype.breezyCloseDialog = (
ajax,
response,
status,
) => {
if ($('#drupal-off-canvas').length) {
// Close off-canvas system tray which is not triggered by close dialog
// command.
// @see Drupal.behaviors.offCanvasEvents
$('#drupal-off-canvas').remove();
$('body').removeClass('js-tray-open');
// Remove all *.off-canvas events
$(document).off('.off-canvas');
$(window).off('.off-canvas');
const edge = document.documentElement.dir === 'rtl' ? 'left' : 'right';
const $mainCanvasWrapper = $('[data-off-canvas-main-canvas]');
$mainCanvasWrapper.get(0).style[`padding-${edge}`] = 0;
// Resize tabs when closing off-canvas system tray.
$(window).trigger('resize.tabs');
}
// https://stackoverflow.com/questions/15763909/jquery-ui-dialog-check-if-exists-by-instance-method
if ($(response.selector).hasClass('ui-dialog-content')) {
Drupal.AjaxCommands.prototype.closeDialog(ajax, response, status);
}
};
/**
* Triggers confirm page reload.
*
* @param {Drupal.Ajax} [ajax]
* A {@link Drupal.ajax} object.
* @param {object} response
* Ajax response.
* @param {string} response.message
* A message to be displayed in the confirm dialog.
*/
Drupal.AjaxCommands.prototype.breezyConfirmReload = (ajax, response) => {
// eslint-disable-next-line no-alert
if (window.confirm(response.message)) {
window.location.reload(true);
}
};
})(jQuery, Drupal, drupalSettings, once);
