0

Whenever a link has a specific class I want to show it as a jQuery modal. I have added the neccesarry data attributes to the link in order to be able to use it as a modal.

I have also created a route for nodes that has a custom controller that is run when a node is viewed with ?_format=json. The controller returns the rendered node as JSON which seems to work fine.

To see the route definition look here.

Here's my controller:

public function json(EntityInterface $node, $view_mode = 'full', $langcode = NULL) {
  $build = $this->entityTypeManager->getViewBuilder('node')->view($node, $view_mode);
  $output = $this->renderer->renderRoot($build);

  return new JsonResponse($output);
}

And here's the JS that makes the link a modal:

if ($(context).find('.class').length > 0) {
  $(context).find('.class').each(function () {
    $(this).attr('data-dialog-type', 'modal').addClass('use-ajax');
  });
}

The only problem is that when clicking the link it gives an error saying:

SyntaxError: JSON.parse: unexpected character at line 2 column 1 of the JSON data

Why does JSON.parse fail to parse the JSON data that JsonResponse generates?

10
  • JsonResponse is a Symfony class, not Drupal. And yes, it sends valid JSON. What has your own debugging led you to understand? Is it valid JSON or not?
    – Clive
    Aug 20 '19 at 9:18
  • I have tried to use JSON.parse() on the JSON data that I receive from my controller, it gives the error, JSON.parse: unexpected ...
    – user72672
    Aug 20 '19 at 9:20
  • Have you run it through an external linter? Tried it in different browsers? Tried returning a known good static JSON that works in other instances? We can't see inside your environment here so you're going to need to do the bulk of the debugging
    – Clive
    Aug 20 '19 at 9:37
  • Yes I tried that too, it was also failing.
    – user72672
    Aug 20 '19 at 9:38
  • 2
    You probably need to pass an array to the JSON constructor, and renderRoot() returns an HTML string.
    – Jaypan
    Aug 20 '19 at 10:48
0

I can suggest you to check with AjaxResponse, it will return the json response object.

$response = new AjaxResponse();

And use below to open content in modal or as dialog.

$response->addCommand(new OpenModalDialogCommand($title, $content, ['width' => '700'])); // To open a modal window

OR

$response->addCommand(new OpenDialogCommand('#some-element', $title, $content, ['width' => '700'])); // to open a dialog window

$title refers to title of your node and $content refers to content that you want to show in the modal. It is also possible to define some properties like width in it.

And in the end just return it's response like below:

return $response;

Remember to include AjaxResponse in it your controller file.

use Drupal\Core\Ajax\AjaxResponse;

I hope the above will solve your problem.

2
  • Hi, thank you for the response. This actually seems to work perfectly. I forgot to include the core/drupal.dialog.ajax library, after including that it all worked. Don't really see why this answer deserves a downvote :)
    – user72672
    Aug 20 '19 at 16:08
  • 1
    That's really good. My main concern was that your problem should be solved and it would make me happy if my little knowledge can help you out. Aug 22 '19 at 6:38

Your Answer

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