/** * @file * Extends the Drupal AJAX functionality to integrate the dialog API. */ (function ($, Drupal) { "use strict"; Drupal.behaviors.dialog = { attach: function (context, settings) { var $context = $(context); // Provide a known 'drupal-modal' DOM element for Drupal-based modal // dialogs. Non-modal dialogs are responsible for creating their own // elements, since there can be multiple non-modal dialogs at a time. if (!$('#drupal-modal').length) { $('
').hide().appendTo('body'); } // Special behaviors specific when attaching content within a dialog. // These behaviors usually fire after a validation error inside a dialog. var $dialog = $context.closest('.ui-dialog-content'); if ($dialog.length) { // Remove and replace the dialog buttons with those from the new form. if ($dialog.dialog('option', 'drupalAutoButtons')) { var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); $dialog.dialog('option', 'buttons', buttons); } // Refocus the first input element after validation errors. if ($context.find('form').length) { $context.find('input:first').focus(); } } }, /** * Scan a dialog for any primary buttons and move them to the button area. * * @param $dialog * An jQuery object containing the element that is the dialog target. * @return * An array of buttons that need to be added to the button area. */ prepareDialogButtons: function ($dialog) { var buttons = []; var $buttons = $dialog.find('.form-actions input[type=submit]'); $buttons.each(function () { // Hidden form buttons need special attention. For browser consistency, // the button needs to be "visible" in order to have the enter key fire // the form submit event. So instead of a simple "hide" or // "display: none", we set its dimensions to zero. // See http://mattsnider.com/how-forms-submit-when-pressing-enter/ var $originalButton = $(this).css({ width: 0, height: 0, padding: 0, border: 0 }); buttons.push({ 'text': $originalButton.html() || $originalButton.attr('value'), 'class': $originalButton.attr('class'), 'click': function (e) { $originalButton.trigger('click'); e.preventDefault(); } }); }); return buttons; } }; /** * Command to open a dialog. */ Drupal.AjaxCommands.prototype.openDialog = function (ajax, response, status) { if (!response.selector) { return false; } var $dialog = $(response.selector); if (!$dialog.length) { // Create the element if needed. $dialog = $('').appendTo('body'); } // Set up the wrapper, if there isn't one. if (!ajax.wrapper) { ajax.wrapper = $dialog.attr('id'); } // Use the ajax.js insert command to populate the dialog contents. response.command = 'insert'; response.method = 'html'; ajax.commands.insert(ajax, response, status); // Move the buttons to the jQuery UI dialog buttons area. if (!response.dialogOptions.buttons) { response.dialogOptions.drupalAutoButtons = true; response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); } // Open the dialog itself. response.dialogOptions = response.dialogOptions || {}; var dialog = Drupal.dialog($dialog, response.dialogOptions); if (response.dialogOptions.modal) { dialog.showModal(); } else { dialog.show(); } }; /** * Command to close a dialog. * * If no selector is given, it defaults to trying to close the modal. */ Drupal.AjaxCommands.prototype.closeDialog = function (ajax, response, status) { var $dialog = $(response.selector); if ($dialog.length) { Drupal.dialog($dialog).close(); if (!response.persist) { $dialog.remove(); } } }; /** * Command to set a dialog property. * * jQuery UI specific way of setting dialog options. */ Drupal.AjaxCommands.prototype.setDialogOption = function (ajax, response, status) { var $dialog = $(response.selector); if ($dialog.length) { $dialog.dialog('option', response.optionName, response.optionValue); } }; /** * Binds a listener on dialog creation to handle the cancel link. */ $(window).on('dialog:aftercreate', function (e, dialog, $element, settings) { $element.on('click.dialog', '.dialog-cancel', function (e) { dialog.close('cancel'); e.preventDefault(); e.stopPropagation(); }); }); /** * Removes all 'dialog' listeners. */ $(window).on('dialog:beforeclose', function (e, dialog, $element) { $element.off('.dialog'); }); })(jQuery, Drupal);