14

After validate with javascript that I'll be able to use the client location:

if (navigator.geolocation) {
...

I need to load the content of a view block with arguments (based in the position coords). I know how to obtain the HTML that I want to put inside the div, so at least I have this part.

I tried to follow the Simple Drupal AJAX load with jQuery and delivery callback article (that is write for Drupal 7 very different from Drupal 8) but I just arrived to load a page in a div (with headers and footer very far from my real objetive).

jQuery('#my-div').load('/admin/help');

Any ideas on how to load content in a div with ajax?

4 Answers 4

20

I've come up with a working solution. It might not be the best approach but it works.

You need to create your routing file:

my_module.routing.yml

diocese_core.path_with_data:
  path: 'path-with-data'
  defaults:
    _controller: '\Drupal\my_module\Controller\MyController::Render'
  requirements:
    _access: 'TRUE'

Creating the controller for your page

src/Controller/MyController.php

<?php

namespace Drupal\my_module\Controller;

use Drupal\Core\Controller\ControllerBase;
use \Symfony\Component\HttpFoundation\Response;

/**
 * An example controller.
 */
class MyController extends ControllerBase {

  /**
   * {@inheritdoc}
   */
  public function Render() {
    $build = array(
      '#type' => 'markup',
      '#markup' => t('Hello World!'),
    );
    // This is the important part, because will render only the TWIG template.
    return new Response(\Drupal::service('renderer')->render($build));
  }

}

And you only need to call in javascript

jQuery('#my-div').load('path-with-data');

An this will be the output once the code is executed:

<div id="my-div">Hello World!</div>

References:

6
  • 3
    If you're interested in learning the "Drupal Way" of doing this watch Demystifying AJAX Callback Commands in Drupal 8
    – No Sssweat
    Mar 21, 2017 at 10:43
  • @NoSssweat Thanks, good tutorial, but in this case I can use this too? Mar 21, 2017 at 12:39
  • Yes, orcourse :), just note that it gets trickier if your loading like a form, as the summit button will not work. Or like a flag, the flag ajax won't work, since it has missing js files. You will have to attach them like this (#5)
    – No Sssweat
    Mar 21, 2017 at 22:14
  • Helpful tip: sometimes you may need to produce simple text output, I needed this to pull just a basic string. USe this method but set your content-type header: $response->headers->set('Content-Type', 'text/plain'); Dec 5, 2018 at 15:58
  • 1
    instead render($build) - > \Drupal::service('renderer')->render($build) Mar 14, 2022 at 12:02
18

This is exactly what you need.

var endpoint = Drupal.url('modal/get-content');
Drupal.ajax({ url: endpoint }).execute();

where endpoint is the URL of your route. So you have controller for your route and this controller has AjaxResponse

public function getContent($modal_id) {
  $response = new AjaxResponse();

  $selector = '.modal.in .modal-body';

  // You can use markup, rendreable array, getForm via form_builder service.
  $content = [
    '#markup' => '....',
  ];

  $response->addCommand(new InvokeCommand($selector, 'removeClass', ['spinner-loading']));
  $response->addCommand(new HtmlCommand($selector, $content));

  return $response;
}
2
  • It's always better to use AjaxResponse and don't render content to string In case, when you have some attachments it will not work when you just render the content. Use ajax command and CommandWithAttachedAssetsTrait will take care about this. Feb 9, 2018 at 14:01
  • Using this method how do you send parameters?
    – Amy
    Aug 12, 2020 at 16:29
6

Add what you need to your build array, and to render without the Page template, you can pass to a new Response object:

$build['view'] = [
  '#type' => 'view',
  '#name' => 'my_view',
  '#display_id' => 'block_1',
  '#arguments' => $view_arguments,
];

$rendered = \Drupal::service('renderer')->renderRoot($build);

$response = new Response();
$response->setContent($rendered);
return $response;
2
  • which is the difference between your code and my code? Just to learn, the use of ajax in Drupal 8 is new to me. Can you provide some references? Mar 13, 2017 at 21:03
  • Only difference is added the view build array, if you want to load a view block.
    – oknate
    Mar 13, 2017 at 21:09
1

I searched for same solution and was very surprised that in a drupal way we need only one line of code:

Drupal.ajax({ url: endpoint }).execute();
3
  • 1
    Where do you add this code? Can you add more information about the solution, please? Feb 6, 2018 at 18:06
  • Found that in a book called "Drupal 8 Module Development" by Daniel Sipos Feb 7, 2018 at 22:14
  • 1
    I have the book but I can't find the example, which page? Feb 8, 2018 at 2:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.