0

I'm building a tool that contains a few clickable regions. Each region has a link with class="use-ajax" data-dialog-type="modal" pointing at a custom form route.

Everything is working great and I'm able to get the data from the form and store it. I, however, need the user's selection in this modal form to be reflected in the region they initially clicked.

I'm at a loss aside from storing their selections in localStorage or something and populating that region when they close each modal. That seems a little hacky though. Is there a cleaner way of accomplishing this that I'm missing?

<div class="region">
    <a class="use-ajax" data-dialog-options="{&quot;width&quot;:550, &quot;dialogClass&quot;: &quot;my-region-class&quot; }" data-dialog-type="modal" href="/route/to/custom/form">
      <div class="content">
      Click to select
      </div>
    </a>
  </div>
3
  • 1
    Why dont you include the region as a parameter in your route? /my-route/{region}
    – d70rr3s
    Jan 13 '20 at 15:23
  • @d70rr3s I think I could do that but I don't fully understand how I would then visually update that content in that region.
    – Vecta
    Jan 13 '20 at 15:29
  • 1
    I mean if you pass down the region to you route you could later on your forms submit return an AJAX command udpating your HTML. I'll provide you an answer using dialog and AJAX callbacks.
    – d70rr3s
    Jan 13 '20 at 15:39
2

You can pass down your region's ID as parameters to your route. For example:

<a class="use-ajax" data-dialog-options="{&quot;width&quot;:550, &quot;dialogClass&quot;: &quot;my-region-class&quot; }" data-dialog-type="modal" href="/route/to/custom/form/this-region">...</a>

As explained here you can add arguments from the route to your form.

On the buildForm method you can have something like this

public function buildForm(array $form, FormStateInterface $form_state, $region = NULL) {
  // Your code...
  $form += [
    'button' => [
      '#type' => 'button',
      '#value' => $this->t('Submit this form),
      '#name' => 'ajax_trigger',
      '#ajax' => [
        'callback' => '::updateRegionAjaxCallback',
        'wrapper' => $region, // Assuming $region is the argument passed down.
        'method' => 'replace',
        'effect' => 'fade',
        'event' => 'click',
      ],
    ],
  ];
}

Later your callback method could look like.

public static function updateRegionAjaxCallback(array $form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  $response->addCommand(new AppendCommand(NULL, [
    // Your render array with the data to be displayed.
    '#cache' => [
      'max-age' => Cache::PERMANENT,
      'contexts' => ['url'],
    ],
  ]));

  return $response;
}

This should work but keep in mind that will be best capture the form submit and triggering a custom AJAX event.

1
  • Thank you for the great answer! This was exactly what I needed!
    – Vecta
    Jan 13 '20 at 18:51

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.