PageSourceSearch

https://www.elbitsystems.com/modules/contrib/webform/js/webform.ajax.js?tlgizz

js elbitsystems.com collected 2026-09-24 09:04:29 UTC 11,935 bytes, 340 lines download raw bytes

1/**
2 * @file
3 * JavaScript behaviors for Ajax.
4 */
5
6(function ($, Drupal, drupalSettings, once, tabbable) {
7  Drupal.webform = Drupal.webform || {};
8  Drupal.webform.ajax = Drupal.webform.ajax || {};
9  // Allow scrollTopOffset to be custom defined or based on whether there is a
10  // floating toolbar.
11  Drupal.webform.ajax.scrollTopOffset = Drupal.webform.ajax.scrollTopOffset || ($('#toolbar-administration').length ? 140 : 10);
12
13  // Set global scroll top offset.
14  // @todo Remove in Webform 6.x.
15  Drupal.webform.scrollTopOffset = Drupal.webform.ajax.scrollTopOffset;
16
17  /**
18   * Provide Webform Ajax link behavior.
19   *
20   * Display fullscreen progress indicator instead of throbber.
21   * Copied from: Drupal.behaviors.AJAX
22   *
23   * @type {Drupal~behavior}
24   *
25   * @prop {Drupal~behaviorAttach} attach
26   *   Attaches the behavior to a.webform-ajax-link.
27   */
28  Drupal.behaviors.webformAjaxLink = {
29    attach(context) {
30      $(once('webform-ajax-link', '.webform-ajax-link', context)).each(function () {
31        var element_settings = {};
32        element_settings.progress = {type: 'fullscreen'};
33
34        // For anchor tags, these will go to the target of the anchor rather
35        // than the usual location.
36        var href = $(this).attr('href');
37        if (href) {
38          element_settings.url = href;
39          element_settings.event = 'click';
40        }
41        element_settings.dialogType = $(this).data('dialog-type');
42        element_settings.dialogRenderer = $(this).data('dialog-renderer');
43        element_settings.dialog = $(this).data('dialog-options');
44        element_settings.base = $(this).attr('id');
45        element_settings.element = this;
46        Drupal.ajax(element_settings);
47
48        // Close all open modal dialogs when opening off-canvas dialog.
49        if (element_settings.dialogRenderer === 'off_canvas') {
50          $(this).on('click', function () {
51            $('.ui-dialog.webform-ui-dialog:visible').find('.ui-dialog-content').dialog('close');
52          });
53        }
54      });
55    }
56  };
57
58  /**
59   * Adds a hash (#) to current pages location for links and buttons
60   *
61   * @type {Drupal~behavior}
62   *
63   * @prop {Drupal~behaviorAttach} attach
64   *   Attaches the behavior to a[data-hash] or :button[data-hash].
65   *
66   * @see \Drupal\webform_ui\WebformUiEntityElementsForm::getElementRow
67   * @see Drupal.behaviors.webformFormTabs
68   */
69  Drupal.behaviors.webformAjaxHash = {
70    attach(context) {
71      $(once('webform-ajax-hash', '[data-hash]', context)).each(function () {
72        var hash = $(this).data('hash');
73        if (hash) {
74          $(this).on('click', function () {
75            location.hash = $(this).data('hash');
76          });
77        }
78      });
79    }
80  };
81
82  /**
83   * Provide Ajax callback for confirmation back to link.
84   *
85   * @type {Drupal~behavior}
86   *
87   * @prop {Drupal~behaviorAttach} attach
88   *   Attaches the behavior to confirmation back to link.
89   */
90  Drupal.behaviors.webformConfirmationBackAjax = {
91    attach(context) {
92      $(once('webform-confirmation-back-ajax', '.js-webform-confirmation-back-link-ajax', context))
93        .on('click', function (event) {
94          var $form = $(this).parents('form');
95
96          // Trigger the Ajax call back for the hidden submit button.
97          // @see \Drupal\webform\WebformSubmissionForm::getCustomForm
98          $form.find('.js-webform-confirmation-back-submit-ajax').trigger('click');
99
100          // Move the progress indicator from the submit button to after this link.
101          // @todo Figure out a better way to set a progress indicator.
102          var $progress_indicator = $form.find('.ajax-progress');
103          if ($progress_indicator) {
104            $(this).after($progress_indicator);
105          }
106
107          // Cancel the click event.
108          event.preventDefault();
109          event.stopPropagation();
110        });
111    }
112  };
113
114  /** ********************************************************************** **/
115  // Ajax commands.
116  /** ********************************************************************** **/
117
118  /**
119   * Track the updated table row key.
120   */
121  var updateKey;
122
123  /**
124   * Track the add element key.
125   */
126  var addElement;
127
128  /**
129   * Command to insert new content into the DOM.
130   *
131   * @param {Drupal.Ajax} ajax
132   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
133   * @param {object} response
134   *   The response from the Ajax request.
135   * @param {string} response.data
136   *   The data to use with the jQuery method.
137   * @param {string} [response.method]
138   *   The jQuery DOM manipulation method to be used.
139   * @param {string} [response.selector]
140   *   A optional jQuery selector string.
141   * @param {object} [response.settings]
142   *   An optional array of settings that will be used.
143   * @param {number} [status]
144   *   The XMLHttpRequest status.
145   */
146  Drupal.AjaxCommands.prototype.webformInsert = function (ajax, response, status) {
147    // Insert the HTML.
148    this.insert(ajax, response, status);
149
150    // Add element.
151    if (addElement) {
152      var addSelector = (addElement === '_root_')
153        ? '#webform-ui-add-element'
154        : '[data-drupal-selector="edit-webform-ui-elements-' + addElement + '-add"]';
155      $(addSelector).trigger('click');
156    }
157
158    // If not add element, then scroll to and highlight the updated table row.
159    if (!addElement && updateKey) {
160      var $element = $('tr[data-webform-key="' + updateKey + '"]');
161
162      // Highlight the updated element's row.
163      $element.addClass('color-success');
164      setTimeout(function () {$element.removeClass('color-success');}, 3000);
165
166      // Focus first tabbable item for the updated elements and handlers.
167      const tabbableElements = tabbable.tabbable($element.get(0));
168      const filteredElements = tabbableElements.filter(element => !element.classList.contains('tabledrag-handle'));
169      if (filteredElements.length) {
170        filteredElements[0].focus();
171      }
172
173      // Scroll element into view.
174      Drupal.webformScrolledIntoView($element);
175    }
176    else {
177      // Focus main content.
178      $('#main-content').trigger('focus');
179    }
180
181    // Display main page's status message in a floating container.
182    var $wrapper = $(response.selector);
183    if ($wrapper.parents('.ui-dialog').length === 0) {
184      var $messages = $wrapper.find('.messages');
185      // If 'add element' don't show any messages.
186      if (addElement) {
187        $messages.remove();
188      }
189      else if ($messages.length) {
190        var $floatingMessage = $('#webform-ajax-messages');
191        if ($floatingMessage.length === 0) {
192          $floatingMessage = $('<div id="webform-ajax-messages" class="webform-ajax-messages"></div>');
193          $('body').append($floatingMessage);
194        }
195        if ($floatingMessage.is(':animated')) {
196          $floatingMessage.stop(true, true);
197        }
198        $floatingMessage.html($messages).show().delay(3000).fadeOut(1000);
199      }
200    }
201
202    updateKey = null; // Reset element update.
203    addElement = null; // Reset add element.
204  };
205
206  /**
207   * Scroll to top ajax command.
208   *
209   * @param {Drupal.Ajax} [ajax]
210   *   A {@link Drupal.ajax} object.
211   * @param {object} response
212   *   Ajax response.
213   * @param {string} response.selector
214   *   Selector to use.
215   *
216   * @see Drupal.AjaxCommands.prototype.viewScrollTop
217   */
218  Drupal.AjaxCommands.prototype.webformScrollTop = function (ajax, response) {
219    // Scroll top.
220    Drupal.webformScrollTop(response.selector, response.target);
221
222    // Focus on the form wrapper content bookmark if
223    // .js-webform-autofocus is not enabled.
224    // @see \Drupal\webform\Form\WebformAjaxFormTrait::buildAjaxForm
225    var $form = $(response.selector + '-content').find('form');
226    if (!$form.hasClass('js-webform-autofocus')) {
227      $(response.selector + '-content').trigger('focus');
228    }
229  };
230
231  /**
232   * Command to refresh the current webform page.
233   *
234   * @param {Drupal.Ajax} [ajax]
235   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
236   * @param {object} response
237   *   The response from the Ajax request.
238   * @param {string} response.url
239   *   The URL to redirect to.
240   * @param {number} [status]
241   *   The XMLHttpRequest status.
242   */
243  Drupal.AjaxCommands.prototype.webformRefresh = function (ajax, response, status) {
244    // Get URL path name.
245    // @see https://stackoverflow.com/questions/6944744/javascript-get-portion-of-url-path
246    var a = document.createElement('a');
247    a.href = response.url;
248    var forceReload = (response.url.match(/\?reload=([^&]+)($|&)/)) ? RegExp.$1 : null;
249    if (forceReload) {
250      response.url = response.url.replace(/\?reload=([^&]+)($|&)/, '');
251      this.redirect(ajax, response, status);
252      return;
253    }
254
255    if (a.pathname === window.location.pathname && $('.webform-ajax-refresh').length) {
256      updateKey = (response.url.match(/[?|&]update=([^&]+)($|&)/)) ? RegExp.$1 : null;
257      addElement = (response.url.match(/[?|&]add_element=([^&]+)($|&)/)) ? RegExp.$1 : null;
258      $('.webform-ajax-refresh').trigger('click');
259      // Ensure the off canvas dialog is always closed and removed.
260      // @see Drupal.AjaxCommands.prototype.closeDialog
261      $('#drupal-off-canvas').hide();
262    }
263    else {
264      // Clear unsaved information flag so that the current webform page
265      // can be redirected.
266      // @see Drupal.behaviors.webformUnsaved.clear
267      if (Drupal.behaviors.webformUnsaved) {
268        Drupal.behaviors.webformUnsaved.clear();
269      }
270
271      // For webform embedded in an iframe, open all redirects in the top
272      // of the browser window.
273      // @see \Drupal\webform_share\Controller\WebformShareController::page
274      if (drupalSettings.webform_share &&
275        drupalSettings.webform_share.page) {
276        window.top.location = response.url;
277      }
278      else {
279        this.redirect(ajax, response, status);
280      }
281    }
282  };
283
284  /**
285   * Command to close a off-canvas and modal dialog.
286   *
287   * If no selector is given, it defaults to trying to close the modal.
288   *
289   * @param {Drupal.Ajax} [ajax]
290   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
291   * @param {object} response
292   *   The response from the Ajax request.
293   * @param {string} response.selector
294   *   Selector to use.
295   * @param {bool} response.persist
296   *   Whether to persist the dialog element or not.
297   * @param {number} [status]
298   *   The HTTP status code.
299   */
300  Drupal.AjaxCommands.prototype.webformCloseDialog = function (ajax, response, status) {
301    if ($('#drupal-off-canvas-wrapper').length) {
302      // Close off-canvas system tray which is not triggered by close dialog
303      // command.
304      // @see Drupal.behaviors.offCanvasEvents
305      $('#drupal-off-canvas-wrapper').remove();
306      $('body').removeClass('js-tray-open');
307      // Remove all *.off-canvas events
308      $(document).off('.off-canvas');
309      $(window).off('.off-canvas');
310      var edge = document.documentElement.dir === 'rtl' ? 'left' : 'right';
311      var $mainCanvasWrapper = $('[data-off-canvas-main-canvas]');
312      $mainCanvasWrapper.css('padding-' + edge, 0);
313
314      // Resize tabs when closing off-canvas system tray.
315      $(window).trigger('resize.tabs');
316    }
317
318    // https://stackoverflow.com/questions/15763909/jquery-ui-dialog-check-if-exists-by-instance-method
319    if ($(response.selector).hasClass('ui-dialog-content')) {
320      this.closeDialog(ajax, response, status);
321    }
322  };
323
324  /**
325   * Triggers confirm page reload.
326   *
327   * @param {Drupal.Ajax} [ajax]
328   *   A {@link Drupal.ajax} object.
329   * @param {object} response
330   *   Ajax response.
331   * @param {string} response.message
332   *   A message to be displayed in the confirm dialog.
333   */
334  Drupal.AjaxCommands.prototype.webformConfirmReload = function (ajax, response) {
335    if (window.confirm(response.message)) {
336      window.location.reload(true);
337    }
338  };
339
340})(jQuery, Drupal, drupalSettings, once, tabbable);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.