Problem
I want to add a link to my content page that will dynamically change/replace content on the page using AJAX.
Solution
The solution here is add a route and to write a call back that will respond accordingly. The only difference here is
- The link is not a a normal link but a link that will load using a AJAX call
- The Response here is also not normal it will be a AjaxResponse
So lets see how we can do this
Fire a AJAX request with a link
Add class 'use-ajax' to a link. The link will be loaded using an Ajax call. Simply this will do. see screenshot and code below
The code that generates the link
public function display() { $build = [ '#markup' => $this->t('Ajax call example! <a class="use-ajax" href="/other-examples/ajax-call"> Ajax call</a> <div class="ajax-wrapper">Change me !!!</div>'), ]; return $build; }
Implementing the response
/** * Route callback for Ajax call. * Only works for Ajax calls. * * @param \Symfony\Component\HttpFoundation\Request $request * * @return \Drupal\Core\Ajax\AjaxResponse */ public function ajaxCall(Request $request) { if (!$request->isXmlHttpRequest()) { throw new NotFoundHttpException(); } $response = new AjaxResponse(); $Selector = '.ajax-wrapper'; //See: https://www.w3schools.com/cssref/css_selectors.asp $content = '<p>Changed !!!</p>'; /*The content that will be replace the matched element(s), either a render array or an HTML string.*/ $settings = ['my-setting' => 'setting',]; /*An array of JavaScript settings to be passed to any attached behaviors.*/ $response->addCommand(new ReplaceCommand($Selector, $content, $settings)); return $response; }
Things to note here is that you need to add reference to the $requets and the Response.
use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; use Symfony\Component\HttpFoundation\Request;
Drupal passes the current request object to any Controller method so you don't need to worry about it. Also that the Response has several parts.
The Selctor which is the element selector in the DOM that the cal will react on.
The content that will be sent dynamically and based on the type of command will change the DOM. In this case it will entirely replace the HTML element that has the class ajax-wrapper
BEFORE
AFTER