Chris@0: /**
Chris@0: * @file
Chris@0: * Handles AJAX submission and response in Views UI.
Chris@0: */
Chris@0:
Chris@17: (function($, Drupal, drupalSettings) {
Chris@0: /**
Chris@0: * Ajax command for highlighting elements.
Chris@0: *
Chris@0: * @param {Drupal.Ajax} [ajax]
Chris@0: * An Ajax object.
Chris@0: * @param {object} response
Chris@0: * The Ajax response.
Chris@0: * @param {string} response.selector
Chris@0: * The selector in question.
Chris@0: * @param {number} [status]
Chris@0: * The HTTP status code.
Chris@0: */
Chris@17: Drupal.AjaxCommands.prototype.viewsHighlight = function(
Chris@17: ajax,
Chris@17: response,
Chris@17: status,
Chris@17: ) {
Chris@0: $('.hilited').removeClass('hilited');
Chris@0: $(response.selector).addClass('hilited');
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Ajax command to set the form submit action in the views modal edit form.
Chris@0: *
Chris@0: * @param {Drupal.Ajax} [ajax]
Chris@0: * An Ajax object.
Chris@0: * @param {object} response
Chris@0: * The Ajax response. Contains .url
Chris@0: * @param {string} [status]
Chris@0: * The XHR status code?
Chris@0: */
Chris@17: Drupal.AjaxCommands.prototype.viewsSetForm = function(
Chris@17: ajax,
Chris@17: response,
Chris@17: status,
Chris@17: ) {
Chris@0: const $form = $('.js-views-ui-dialog form');
Chris@0: // Identify the button that was clicked so that .ajaxSubmit() can use it.
Chris@0: // We need to do this for both .click() and .mousedown() since JavaScript
Chris@0: // code might trigger either behavior.
Chris@17: const $submitButtons = $form
Chris@17: .find('input[type=submit].js-form-submit, button.js-form-submit')
Chris@17: .once('views-ajax-submit');
Chris@17: $submitButtons.on('click mousedown', function() {
Chris@0: this.form.clk = this;
Chris@0: });
Chris@17: $form.once('views-ajax-submit').each(function() {
Chris@0: const $form = $(this);
Chris@14: const elementSettings = {
Chris@0: url: response.url,
Chris@0: event: 'submit',
Chris@0: base: $form.attr('id'),
Chris@0: element: this,
Chris@0: };
Chris@14: const ajaxForm = Drupal.ajax(elementSettings);
Chris@0: ajaxForm.$form = $form;
Chris@0: });
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Ajax command to show certain buttons in the views edit form.
Chris@0: *
Chris@0: * @param {Drupal.Ajax} [ajax]
Chris@0: * An Ajax object.
Chris@0: * @param {object} response
Chris@0: * The Ajax response.
Chris@0: * @param {bool} response.changed
Chris@0: * Whether the state changed for the buttons or not.
Chris@0: * @param {number} [status]
Chris@0: * The HTTP status code.
Chris@0: */
Chris@17: Drupal.AjaxCommands.prototype.viewsShowButtons = function(
Chris@17: ajax,
Chris@17: response,
Chris@17: status,
Chris@17: ) {
Chris@0: $('div.views-edit-view div.form-actions').removeClass('js-hide');
Chris@0: if (response.changed) {
Chris@0: $('div.views-edit-view div.view-changed.messages').removeClass('js-hide');
Chris@0: }
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Ajax command for triggering preview.
Chris@0: *
Chris@0: * @param {Drupal.Ajax} [ajax]
Chris@0: * An Ajax object.
Chris@0: * @param {object} [response]
Chris@0: * The Ajax response.
Chris@0: * @param {number} [status]
Chris@0: * The HTTP status code.
Chris@0: */
Chris@17: Drupal.AjaxCommands.prototype.viewsTriggerPreview = function(
Chris@17: ajax,
Chris@17: response,
Chris@17: status,
Chris@17: ) {
Chris@0: if ($('input#edit-displays-live-preview').is(':checked')) {
Chris@0: $('#preview-submit').trigger('click');
Chris@0: }
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Ajax command to replace the title of a page.
Chris@0: *
Chris@0: * @param {Drupal.Ajax} [ajax]
Chris@0: * An Ajax object.
Chris@0: * @param {object} response
Chris@0: * The Ajax response.
Chris@0: * @param {string} response.siteName
Chris@0: * The site name.
Chris@0: * @param {string} response.title
Chris@0: * The new page title.
Chris@0: * @param {number} [status]
Chris@0: * The HTTP status code.
Chris@0: */
Chris@17: Drupal.AjaxCommands.prototype.viewsReplaceTitle = function(
Chris@17: ajax,
Chris@17: response,
Chris@17: status,
Chris@17: ) {
Chris@0: const doc = document;
Chris@0: // For the
element, make a best-effort attempt to replace the page
Chris@0: // title and leave the site name alone. If the theme doesn't use the site
Chris@0: // name in the element, this will fail.
Chris@0: const oldTitle = doc.title;
Chris@0: // Escape the site name, in case it has special characters in it, so we can
Chris@0: // use it in our regex.
Chris@17: const escapedSiteName = response.siteName.replace(
Chris@17: /[-[\]{}()*+?.,\\^$|#\s]/g,
Chris@17: '\\$&',
Chris@17: );
Chris@0: const re = new RegExp(`.+ (.) ${escapedSiteName}`);
Chris@17: doc.title = oldTitle.replace(
Chris@17: re,
Chris@17: `${response.title} $1 ${response.siteName}`,
Chris@17: );
Chris@0:
Chris@0: $('h1.page-title').text(response.title);
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Get rid of irritating tabledrag messages.
Chris@0: *
Chris@0: * @return {Array}
Chris@0: * An array of messages. Always empty array, to get rid of the messages.
Chris@0: */
Chris@17: Drupal.theme.tableDragChangedWarning = function() {
Chris@0: return [];
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Trigger preview when the "live preview" checkbox is checked.
Chris@0: *
Chris@0: * @type {Drupal~behavior}
Chris@0: *
Chris@0: * @prop {Drupal~behaviorAttach} attach
Chris@0: * Attaches behavior to trigger live preview if the live preview option is
Chris@0: * checked.
Chris@0: */
Chris@0: Drupal.behaviors.livePreview = {
Chris@0: attach(context) {
Chris@17: $('input#edit-displays-live-preview', context)
Chris@17: .once('views-ajax')
Chris@17: .on('click', function() {
Chris@17: if ($(this).is(':checked')) {
Chris@17: $('#preview-submit').trigger('click');
Chris@17: }
Chris@17: });
Chris@0: },
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Sync preview display.
Chris@0: *
Chris@0: * @type {Drupal~behavior}
Chris@0: *
Chris@0: * @prop {Drupal~behaviorAttach} attach
Chris@0: * Attaches behavior to sync the preview display when needed.
Chris@0: */
Chris@0: Drupal.behaviors.syncPreviewDisplay = {
Chris@0: attach(context) {
Chris@17: $('#views-tabset a')
Chris@17: .once('views-ajax')
Chris@17: .on('click', function() {
Chris@17: const href = $(this).attr('href');
Chris@17: // Cut of #views-tabset.
Chris@17: const displayId = href.substr(11);
Chris@17: // Set the form element.
Chris@17: $('#views-live-preview #preview-display-id').val(displayId);
Chris@17: });
Chris@0: },
Chris@0: };
Chris@0:
Chris@0: /**
Chris@0: * Ajax behaviors for the views_ui module.
Chris@0: *
Chris@0: * @type {Drupal~behavior}
Chris@0: *
Chris@0: * @prop {Drupal~behaviorAttach} attach
Chris@0: * Attaches ajax behaviors to the elements with the classes in question.
Chris@0: */
Chris@0: Drupal.behaviors.viewsAjax = {
Chris@0: collapseReplaced: false,
Chris@0: attach(context, settings) {
Chris@14: const baseElementSettings = {
Chris@0: event: 'click',
Chris@0: progress: { type: 'fullscreen' },
Chris@0: };
Chris@0: // Bind AJAX behaviors to all items showing the class.
Chris@17: $('a.views-ajax-link', context)
Chris@17: .once('views-ajax')
Chris@17: .each(function() {
Chris@17: const elementSettings = baseElementSettings;
Chris@17: elementSettings.base = $(this).attr('id');
Chris@17: elementSettings.element = this;
Chris@17: // Set the URL to go to the anchor.
Chris@17: if ($(this).attr('href')) {
Chris@17: elementSettings.url = $(this).attr('href');
Chris@17: }
Chris@17: Drupal.ajax(elementSettings);
Chris@17: });
Chris@0:
Chris@0: $('div#views-live-preview a')
Chris@17: .once('views-ajax')
Chris@17: .each(function() {
Chris@0: // We don't bind to links without a URL.
Chris@0: if (!$(this).attr('href')) {
Chris@0: return true;
Chris@0: }
Chris@0:
Chris@14: const elementSettings = baseElementSettings;
Chris@0: // Set the URL to go to the anchor.
Chris@14: elementSettings.url = $(this).attr('href');
Chris@17: if (
Chris@17: Drupal.Views.getPath(elementSettings.url).substring(0, 21) !==
Chris@17: 'admin/structure/views'
Chris@17: ) {
Chris@0: return true;
Chris@0: }
Chris@0:
Chris@14: elementSettings.wrapper = 'views-preview-wrapper';
Chris@14: elementSettings.method = 'replaceWith';
Chris@14: elementSettings.base = $(this).attr('id');
Chris@14: elementSettings.element = this;
Chris@14: Drupal.ajax(elementSettings);
Chris@0: });
Chris@0:
Chris@0: // Within a live preview, make exposed widget form buttons re-trigger the
Chris@0: // Preview button.
Chris@0: // @todo Revisit this after fixing Views UI to display a Preview outside
Chris@0: // of the main Edit form.
Chris@0: $('div#views-live-preview input[type=submit]')
Chris@17: .once('views-ajax')
Chris@17: .each(function(event) {
Chris@17: $(this).on('click', function() {
Chris@0: this.form.clk = this;
Chris@0: return true;
Chris@0: });
Chris@14: const elementSettings = baseElementSettings;
Chris@0: // Set the URL to go to the anchor.
Chris@14: elementSettings.url = $(this.form).attr('action');
Chris@17: if (
Chris@17: Drupal.Views.getPath(elementSettings.url).substring(0, 21) !==
Chris@17: 'admin/structure/views'
Chris@17: ) {
Chris@0: return true;
Chris@0: }
Chris@0:
Chris@14: elementSettings.wrapper = 'views-preview-wrapper';
Chris@14: elementSettings.method = 'replaceWith';
Chris@14: elementSettings.event = 'click';
Chris@14: elementSettings.base = $(this).attr('id');
Chris@14: elementSettings.element = this;
Chris@0:
Chris@14: Drupal.ajax(elementSettings);
Chris@0: });
Chris@0: },
Chris@0: };
Chris@17: })(jQuery, Drupal, drupalSettings);