RenderElement::preRenderAjaxForm

public static RenderElement::preRenderAjaxForm($element)

Adds Ajax information about an element to communicate with JavaScript.

If #ajax is set on an element, this additional JavaScript is added to the page header to attach the Ajax behaviors. See ajax.js for more information.

Parameters

array $element: An associative array containing the properties of the element. Properties used:

  • #ajax['event']
  • #ajax['prevent']
  • #ajax['url']
  • #ajax['callback']
  • #ajax['options']
  • #ajax['wrapper']
  • #ajax['parameters']
  • #ajax['effect']
  • #ajax['accepts']

Return value

array The processed element with the necessary JavaScript attached to it.

File

core/lib/Drupal/Core/Render/Element/RenderElement.php, line 254

Class

RenderElement
Provides a base class for render element plugins.

Namespace

Drupal\Core\Render\Element

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
public static function preRenderAjaxForm($element) {
  // Skip already processed elements.
  if (isset($element['#ajax_processed'])) {
    return $element;
  }
  // Initialize #ajax_processed, so we do not process this element again.
  $element['#ajax_processed'] = FALSE;
 
  // Nothing to do if there are no Ajax settings.
  if (empty($element['#ajax'])) {
    return $element;
  }
 
  // Add a data attribute to disable automatic refocus after ajax call.
  if (!empty($element['#ajax']['disable-refocus'])) {
    $element['#attributes']['data-disable-refocus'] = "true";
  }
 
  // Add a reasonable default event handler if none was specified.
  if (isset($element['#ajax']) && !isset($element['#ajax']['event'])) {
    switch ($element['#type']) {
      case 'submit':
      case 'button':
      case 'image_button':
        // Pressing the ENTER key within a textfield triggers the click event of
        // the form's first submit button. Triggering Ajax in this situation
        // leads to problems, like breaking autocomplete textfields, so we bind
        // to mousedown instead of click.
        // @see https://www.drupal.org/node/216059
        $element['#ajax']['event'] = 'mousedown';
        // Retain keyboard accessibility by setting 'keypress'. This causes
        // ajax.js to trigger 'event' when SPACE or ENTER are pressed while the
        // button has focus.
        $element['#ajax']['keypress'] = TRUE;
        // Binding to mousedown rather than click means that it is possible to
        // trigger a click by pressing the mouse, holding the mouse button down
        // until the Ajax request is complete and the button is re-enabled, and
        // then releasing the mouse button. Set 'prevent' so that ajax.js binds
        // an additional handler to prevent such a click from triggering a
        // non-Ajax form submission. This also prevents a textfield's ENTER
        // press triggering this button's non-Ajax form submission behavior.
        if (!isset($element['#ajax']['prevent'])) {
          $element['#ajax']['prevent'] = 'click';
        }
        break;
 
      case 'password':
      case 'textfield':
      case 'number':
      case 'tel':
      case 'textarea':
        $element['#ajax']['event'] = 'blur';
        break;
 
      case 'radio':
      case 'checkbox':
      case 'select':
        $element['#ajax']['event'] = 'change';
        break;
 
      case 'link':
        $element['#ajax']['event'] = 'click';
        break;
 
      default:
        return $element;
    }
  }
 
  // Attach JavaScript settings to the element.
  if (isset($element['#ajax']['event'])) {
    $element['#attached']['library'][] = 'core/jquery.form';
    $element['#attached']['library'][] = 'core/drupal.ajax';
 
    $settings = $element['#ajax'];
 
    // Assign default settings. When 'url' is set to NULL, ajax.js submits the
    // Ajax request to the same URL as the form or link destination is for
    // someone with JavaScript disabled. This is generally preferred as a way to
    // ensure consistent server processing for js and no-js users, and Drupal's
    // content negotiation takes care of formatting the response appropriately.
    // However, 'url' and 'options' may be set when wanting server processing
    // to be substantially different for a JavaScript triggered submission.
    $settings += [
      'url' => NULL,
      'options' => ['query' => []],
      'dialogType' => 'ajax',
    ];
    if (array_key_exists('callback', $settings) && !isset($settings['url'])) {
      $settings['url'] = Url::fromRoute('<current>');
      // Add all the current query parameters in order to ensure that we build
      // the same form on the AJAX POST requests. For example,
      // \Drupal\user\AccountForm takes query parameters into account in order
      // to hide the password field dynamically.
      $settings['options']['query'] += \Drupal::request()->query->all();
      $settings['options']['query'][FormBuilderInterface::AJAX_FORM_REQUEST] = TRUE;
    }
 
    // @todo Legacy support. Remove in Drupal 8.
    if (isset($settings['method']) && $settings['method'] == 'replace') {
      $settings['method'] = 'replaceWith';
    }
 
    // Convert \Drupal\Core\Url object to string.
    if (isset($settings['url']) && $settings['url'] instanceof Url) {
      $url = $settings['url']->setOptions($settings['options'])->toString(TRUE);
      BubbleableMetadata::createFromRenderArray($element)
        ->merge($url)
        ->applyTo($element);
      $settings['url'] = $url->getGeneratedUrl();
    }
    else {
      $settings['url'] = NULL;
    }
    unset($settings['options']);
 
    // Add special data to $settings['submit'] so that when this element
    // triggers an Ajax submission, Drupal's form processing can determine which
    // element triggered it.
    // @see _form_element_triggered_scripted_submission()
    if (isset($settings['trigger_as'])) {
      // An element can add a 'trigger_as' key within #ajax to make the element
      // submit as though another one (for example, a non-button can use this
      // to submit the form as though a button were clicked). When using this,
      // the 'name' key is always required to identify the element to trigger
      // as. The 'value' key is optional, and only needed when multiple elements
      // share the same name, which is commonly the case for buttons.
      $settings['submit']['_triggering_element_name'] = $settings['trigger_as']['name'];
      if (isset($settings['trigger_as']['value'])) {
        $settings['submit']['_triggering_element_value'] = $settings['trigger_as']['value'];
      }
      unset($settings['trigger_as']);
    }
    elseif (isset($element['#name'])) {
      // Most of the time, elements can submit as themselves, in which case the
      // 'trigger_as' key isn't needed, and the element's name is used.
      $settings['submit']['_triggering_element_name'] = $element['#name'];
      // If the element is a (non-image) button, its name may not identify it
      // uniquely, in which case a match on value is also needed.
      // @see _form_button_was_clicked()
      if (!empty($element['#is_button']) && empty($element['#has_garbage_value'])) {
        $settings['submit']['_triggering_element_value'] = $element['#value'];
      }
    }
 
    // Convert a simple #ajax['progress'] string into an array.
    if (isset($settings['progress']) && is_string($settings['progress'])) {
      $settings['progress'] = array('type' => $settings['progress']);
    }
    // Change progress path to a full URL.
    if (isset($settings['progress']['url']) && $settings['progress']['url'] instanceof Url) {
      $settings['progress']['url'] = $settings['progress']['url']->toString();
    }
 
    $element['#attached']['drupalSettings']['ajax'][$element['#id']] = $settings;
    $element['#attached']['drupalSettings']['ajaxTrustedUrl'][$settings['url']] = TRUE;
 
    // Indicate that Ajax processing was successful.
    $element['#ajax_processed'] = TRUE;
  }
  return $element;
}
doc_Drupal
2025-01-10 15:47:30
Comments
Leave a Comment

Please login to continue.