/** * @file * dialog.ajax.js */ (function ($, Drupal, Bootstrap) { Drupal.behaviors.dialog.ajaxCurrentButton = null; Drupal.behaviors.dialog.ajaxOriginalButton = null; // Intercept the success event to add the dialog type to commands. var success = Drupal.Ajax.prototype.success; Drupal.Ajax.prototype.success = function (response, status) { if (this.dialogType) { for (var i = 0, l = response.length; i < l; i++) { if (response[i].dialogOptions) { response[i].dialogType = response[i].dialogOptions.dialogType = this.dialogType; response[i].$trigger = response[i].dialogOptions.$trigger = $(this.element); } } } return success.apply(this, [response, status]); }; var beforeSerialize = Drupal.Ajax.prototype.beforeSerialize; Drupal.Ajax.prototype.beforeSerialize = function (element, options) { // Add the dialog type currently in use. if (this.dialogType) { options.data['ajax_page_state[dialogType]'] = this.dialogType; // Add the dialog element ID if it can be found (useful for closing it). var id = $(this.element).parents('.js-drupal-dialog:first').attr('id'); if (id) { options.data['ajax_page_state[dialogId]'] = id; } } return beforeSerialize.apply(this, arguments); }; /** * Synchronizes a faux button with its original counterpart. * * @param {Boolean} [reset = false] * Whether to reset the current and original buttons after synchronizing. */ Drupal.behaviors.dialog.ajaxUpdateButtons = function (reset) { if (this.ajaxCurrentButton && this.ajaxOriginalButton) { this.ajaxCurrentButton.html(this.ajaxOriginalButton.html() || this.ajaxOriginalButton.attr('value')); this.ajaxCurrentButton.prop('disabled', this.ajaxOriginalButton.prop('disabled')); } if (reset) { this.ajaxCurrentButton = null; this.ajaxOriginalButton = null; } }; $(document) .ajaxSend(function () { Drupal.behaviors.dialog.ajaxUpdateButtons(); }) .ajaxComplete(function () { Drupal.behaviors.dialog.ajaxUpdateButtons(true); }) ; /** * {@inheritdoc} */ Drupal.behaviors.dialog.prepareDialogButtons = function prepareDialogButtons($dialog) { var _this = this; var buttons = []; var $buttons = $dialog.find('.form-actions').find('button, input[type=submit], a.button, .btn'); $buttons.each(function () { var $originalButton = $(this) // Prevent original button from being tabbed to. .attr('tabindex', -1) // Visually make the original button invisible, but don't actually hide // or remove it from the DOM because the click needs to be proxied from // the faux button created in the footer to its original counterpart. .css({ display: 'block', width: 0, height: 0, padding: 0, border: 0, overflow: 'hidden' }); buttons.push({ // Strip all HTML from the actual text value. This value is escaped. // It actual HTML value will be synced with the original button's HTML // below in the "create" method. text: Bootstrap.stripHtml($originalButton) || $originalButton.attr('value'), class: $originalButton.attr('class').replace('use-ajax-submit', ''), click: function click(e) { e.preventDefault(); e.stopPropagation(); _this.ajaxCurrentButton = $(e.target); _this.ajaxOriginalButton = $originalButton; // Some core JS binds dialog buttons to the mousedown or mouseup // events instead of click; all three events must be simulated here. // @see https://www.drupal.org/project/bootstrap/issues/3016254 Bootstrap.simulate($originalButton, ['mousedown', 'mouseup', 'click']); }, create: function () { _this.ajaxCurrentButton = $(this); _this.ajaxOriginalButton = $originalButton; _this.ajaxUpdateButtons(true); } }); }); return buttons; }; })(window.jQuery, window.Drupal, window.Drupal.bootstrap);