I'm trying to implement a hook_form_alter method to modify the behaviour of one field through ajax callback in the form display of node.
The idea is when I select one option from the select list field (field_country) modify the values of other field list (field_laws). Specificly, when I select one country, the hook method pass this value (current) through ajax callback to changeLawsData. This callback get one external service that returns one array of values filtered by the country selected previously.
The issue is inside of callback method, i can't access to $form and $form_state objects that contain the previous hook_form_alter.
My question is: Is posible to pass by arguments this objects to the callback? With this i could handler the state of form and its field, for example.
Something like this:
$form['field_country']['widget']['#ajax'] = array(
'callback' => [$this,'changeLawsData'],
'event' => 'change',
'disable-refocus' => FALSE,
**'arguments' = array($form, $form_state)**
);
Here is the full code of this implementation.
<?php
namespace Drupal\obs_urban_system\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
/**
* Our event subscriber class.
*/
class NodeUrbanSystemFormAlterEventSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
HookEventDispatcherInterface::FORM_ALTER => 'hookFormAlter'
];
}
/**
* Implements hook_form_alter
*/
public function hookFormAlter($event) {
if($event->getFormId() == 'node_urban_system_edit_form') {
$form = $event->getForm();
$country = $form['field_country']['widget']['#default_value'];
$form['field_laws']['widget'][0]['value']['#options'] = \Drupal::service('custom_services.law')->getLawsByContent($country, 'country');
$form['field_law_articles']['widget'][0]['value']['#options'] = \Drupal::service('custom_services.law')->getLawArticlesByCountry($country);
$form['field_country']['widget']['#ajax'] = array(
'callback' => [$this,'changeLawsData'],
'event' => 'change',
'disable-refocus' => FALSE
);
$event->setForm($form);
}
}
/**
* @param $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @return \Drupal\Core\Ajax\AjaxResponse
*/
function changeLawsData(&$form, FormStateInterface $form_state) {
<!--- HERE IM USING THE $form object --->
$country = $form['field_country']['widget']['#default_value'];
<!--- --->
$laws = \Drupal::service('custom_services.law')->getLawsByContent($country, 'country');
foreach ($laws as $key => $value) {
$option .= "<option value='" . $key . "'>" . $value . " </option>";
}
$response = new AjaxResponse();
$response->addCommand(new HtmlCommand('#edit-field-laws-0-value', $option));
return $response;
}
}
Thanks to all very much.