3 namespace Drupal\ajax_test\Controller;
5 use Drupal\Core\Ajax\AjaxResponse;
6 use Drupal\Core\Ajax\AlertCommand;
7 use Drupal\Core\Ajax\CloseDialogCommand;
8 use Drupal\Core\Ajax\HtmlCommand;
10 use Symfony\Component\HttpFoundation\Request;
13 * Provides content for dialog tests.
15 class AjaxTestController {
18 * Example content for dialog testing.
21 * Renderable array of AJAX dialog contents.
23 public static function dialogContents() {
24 // This is a regular render array; the keys do not have special meaning.
26 '#title' => '<em>AJAX Dialog & contents</em>',
28 '#markup' => 'Example message',
33 '#url' => Url::fromRoute('<front>'),
35 // This is a special class to which JavaScript assigns dialog closing
37 'class' => ['dialog-cancel'],
46 * Example content for testing the wrapper of the response.
52 * Renderable array of AJAX response contents.
54 public function renderTypes($type) {
56 '#title' => '<em>AJAX Dialog & contents</em>',
58 '#type' => 'inline_template',
59 '#template' => $this->getRenderTypes()[$type]['render'],
65 * Returns a render array of links that directly Drupal.ajax().
68 * Renderable array of AJAX response contents.
70 public function insertLinksBlockWrapper() {
78 '#markup' => '<div class="ajax-target-wrapper"><div id="ajax-target">Target</div></div>',
82 '#attached' => ['library' => ['ajax_test/ajax_insert']],
85 foreach ($methods as $method) {
86 foreach ($this->getRenderTypes() as $type => $item) {
87 $class = 'ajax-insert';
88 $build['links']['links']['#links']["$method-$type"] = [
89 'title' => "Link $method $type",
90 'url' => Url::fromRoute('ajax_test.ajax_render_types', ['type' => $type]),
93 'data-method' => $method,
94 'data-effect' => $item['effect'],
103 * Returns a render array of links that directly Drupal.ajax().
106 * Renderable array of AJAX response contents.
108 public function insertLinksInlineWrapper() {
116 '#markup' => '<div class="ajax-target-wrapper"><span id="ajax-target-inline">Target inline</span></div>',
120 '#attached' => ['library' => ['ajax_test/ajax_insert']],
123 foreach ($methods as $method) {
124 foreach ($this->getRenderTypes() as $type => $item) {
125 $class = 'ajax-insert-inline';
126 $build['links']['links']['#links']["$method-$type"] = [
127 'title' => "Link $method $type",
128 'url' => Url::fromRoute('ajax_test.ajax_render_types', ['type' => $type]),
131 'data-method' => $method,
132 'data-effect' => $item['effect'],
141 * Returns a render array that will be rendered by AjaxRenderer.
143 * Verifies that the response incorporates JavaScript settings generated
144 * during the page request by adding a dummy setting.
146 public function render() {
150 'core/drupalSettings',
152 'drupalSettings' => [
160 * Returns the used theme.
162 public function theme() {
164 '#markup' => 'Current theme: ' . \Drupal::theme()->getActiveTheme()->getName(),
169 * Returns an AjaxResponse; settings command set last.
171 * Helps verifying AjaxResponse reorders commands to ensure correct execution.
173 public function order() {
174 $response = new AjaxResponse();
175 // HTML insertion command.
176 $response->addCommand(new HtmlCommand('body', 'Hello, world!'));
177 $build['#attached']['library'][] = 'ajax_test/order';
178 $response->setAttachments($build['#attached']);
184 * Returns an AjaxResponse with alert command.
186 * @param \Symfony\Component\HttpFoundation\Request $request
187 * The current request object.
189 * @return \Drupal\Core\Ajax\AjaxResponse
190 * The JSON response object.
192 public function renderError(Request $request) {
194 $query = $request->query;
195 if ($query->has('message')) {
196 $message = $query->get('message');
198 $response = new AjaxResponse();
199 $response->addCommand(new AlertCommand($message));
204 * Returns a render array of form elements and links for dialog.
206 public function dialog() {
207 // Add two wrapper elements for testing non-modal dialogs. Modal dialogs use
208 // the global drupal-modal wrapper by default.
209 $build['dialog_wrappers'] = ['#markup' => '<div id="ajax-test-dialog-wrapper-1"></div><div id="ajax-test-dialog-wrapper-2"></div>'];
211 // Dialog behavior applied to a button.
212 $build['form'] = \Drupal::formBuilder()->getForm('Drupal\ajax_test\Form\AjaxTestDialogForm');
214 // Dialog behavior applied to a #type => 'link'.
217 '#title' => 'Link 1 (modal)',
218 '#url' => Url::fromRoute('ajax_test.dialog_contents'),
220 'class' => ['use-ajax'],
221 'data-dialog-type' => 'modal',
225 // Dialog behavior applied to links rendered by links.html.twig.
230 'title' => 'Link 2 (modal)',
231 'url' => Url::fromRoute('ajax_test.dialog_contents'),
233 'class' => ['use-ajax'],
234 'data-dialog-type' => 'modal',
235 'data-dialog-options' => json_encode([
241 'title' => 'Link 3 (non-modal)',
242 'url' => Url::fromRoute('ajax_test.dialog_contents'),
244 'class' => ['use-ajax'],
245 'data-dialog-type' => 'dialog',
246 'data-dialog-options' => json_encode([
247 'target' => 'ajax-test-dialog-wrapper-1',
253 'title' => 'Link 4 (close non-modal if open)',
254 'url' => Url::fromRoute('ajax_test.dialog_close'),
256 'class' => ['use-ajax'],
257 'data-dialog-type' => 'modal',
261 'title' => 'Link 5 (form)',
262 'url' => Url::fromRoute('ajax_test.dialog_form'),
264 'class' => ['use-ajax'],
265 'data-dialog-type' => 'modal',
269 'title' => 'Link 6 (entity form)',
270 'url' => Url::fromRoute('contact.form_add'),
272 'class' => ['use-ajax'],
273 'data-dialog-type' => 'modal',
274 'data-dialog-options' => json_encode([
281 'title' => 'Link 7 (non-modal, no target)',
282 'url' => Url::fromRoute('ajax_test.dialog_contents'),
284 'class' => ['use-ajax'],
285 'data-dialog-type' => 'dialog',
286 'data-dialog-options' => json_encode([
292 'title' => 'Link 8 (ajax)',
293 'url' => Url::fromRoute('ajax_test.admin.theme'),
295 'class' => ['use-ajax'],
296 'data-dialog-type' => 'modal',
297 'data-dialog-options' => json_encode([
309 * Returns an AjaxResponse with command to close dialog.
311 * @return \Drupal\Core\Ajax\AjaxResponse
312 * The JSON response object.
314 public function dialogClose() {
315 $response = new AjaxResponse();
316 $response->addCommand(new CloseDialogCommand('#ajax-test-dialog-wrapper-1'));
326 protected function getRenderTypes() {
327 $render_single_root = [
328 'pre-wrapped-div' => '<div class="pre-wrapped">pre-wrapped<script> var test;</script></div>',
329 'pre-wrapped-span' => '<span class="pre-wrapped">pre-wrapped<script> var test;</script></span>',
330 'pre-wrapped-whitespace' => ' <div class="pre-wrapped-whitespace">pre-wrapped-whitespace</div>' . "\r\n",
331 'not-wrapped' => 'not-wrapped',
332 'comment-string-not-wrapped' => '<!-- COMMENT -->comment-string-not-wrapped',
333 'comment-not-wrapped' => '<!-- COMMENT --><div class="comment-not-wrapped">comment-not-wrapped</div>',
334 'svg' => '<svg xmlns="http://www.w3.org/2000/svg" width="10" height="10"><rect x="0" y="0" height="10" width="10" fill="green"/></svg>',
337 $render_multiple_root = [
338 'mixed' => ' foo <!-- COMMENT --> foo bar<div class="a class"><p>some string</p></div> additional not wrapped strings, <!-- ANOTHER COMMENT --> <p>final string</p>',
339 'top-level-only' => '<div>element #1</div><div>element #2</div>',
340 'top-level-only-pre-whitespace' => ' <div>element #1</div><div>element #2</div> ',
341 'top-level-only-middle-whitespace-span' => '<span>element #1</span> <span>element #2</span>',
342 'top-level-only-middle-whitespace-div' => '<div>element #1</div> <div>element #2</div>',
346 foreach ($render_single_root as $key => $render) {
347 $render_info[$key] = ['render' => $render, 'effect' => 'fade'];
349 foreach ($render_multiple_root as $key => $render) {
350 $render_info[$key] = ['render' => $render, 'effect' => 'none'];
351 $render_info["$key--effect"] = ['render' => $render, 'effect' => 'fade'];