5

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?

12

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(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:

  • If you're interested in learning the "Drupal Way" of doing this watch Demystifying AJAX Callback Commands in Drupal 8 – No Sssweat Mar 21 '17 at 10:43
  • @NoSssweat Thanks, good tutorial, but in this case I can use this too? – Adrian Cid Almaguer Mar 21 '17 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 '17 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'); – ben.hamelin Dec 5 '18 at 15:58
7

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;
}
  • 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. – Alex Kuzava Feb 9 '18 at 14:01
4

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;
  • 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? – Adrian Cid Almaguer Mar 13 '17 at 21:03
  • Only difference is added the view build array, if you want to load a view block. – oknate Mar 13 '17 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();
  • 1
    Where do you add this code? Can you add more information about the solution, please? – Adrian Cid Almaguer Feb 6 '18 at 18:06
  • Found that in a book called "Drupal 8 Module Development" by Daniel Sipos – Lauris Kuznecovs Feb 7 '18 at 22:14
  • 1
    I have the book but I can't find the example, which page? – Adrian Cid Almaguer Feb 8 '18 at 2:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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