Drupal8 ajax with paragraphs alter

I had the following challenge

when updating taxonomy reference dropdown, it should display field image

See final result:

Gif when choosing a dropdown option from taxonomy reference, it does change image

but a bit more complex when adding a couple paragraphs to it

for instance I had content type

aerial_detail (paragraph) which has aerdet_package and has an another paragraph then field_aerpack_type which is taxonomy reference

and from there when choosing for instance an option it should display image field! fund, right :) ?

 

Here's code:

// This comes from hook_form_alter().

    $form['field_aerial_detail']['widget'][0]['subform']['field_aerdet_package']['widget'][0]['subform']['field_aerpack_type']['widget']['#ajax'] = [
      'callback' => 'getImageAirpackType',
    ];
    $form['field_aerial_detail']['widget'][0]['subform']['field_aerdet_package']['widget'][0]['subform']['field_aerpack_type']['widget']['#suffix'] = '';

//--- and this is the ajax callback implementation.---
function getImageAirpackType(array &$form, FormStateInterface $form_state) {
  $response = new AjaxResponse();
  $field_aerpack_type = $form_state->getValue(['field_aerial_detail', '0', 'subform', 'field_aerdet_package', '0', 'subform', 'field_aerpack_type']);
  $aerpack_type = !empty($field_aerpack_type[0]['target_id']) ? Term::load($field_aerpack_type[0]['target_id']) : '';
  if (!empty($aerpack_type->field_image->entity)) {
    $image = [
      '#theme' => 'image_style',
      '#style_name' => 'thumbnail', ///< @TODO: TBD with themer.
      '#uri' => $aerpack_type->field_image->entity->getFileUri(),
    ];
  }

  $response->addCommand(new HtmlCommand('.airpack-type-image', $image));
  return $response;
}

First we do a form alter!

see the common pattern "widget"(which help us to get form properties inside a field from a node form alter...)

And notice "subform" which go deeper to paragraphs! repeats over and over till get the field.

Once identified the field we need to use "#ajax" property and we need to pass callback which will be a function which will be declared on the .module

notice as well we use #suffix with span class="airpack-type-image" where we are going to insert image.

 

Now comes the tricky part! we need to get field value!

according to documentation says:

string|array $key: Values are stored as a multi-dimensional associative array. If $key is a string, it will return $values[$key]. If $key is an array, each element of the array will be used as a nested key. If $key = array('foo', 'bar') it will return $values['foo']['bar’].

Not so clear, right?

well first we need to do a dpm($form['field_aerial_detail']['widget'][0]['subform']['field_aerdet_package']['widget'][0]['subform']['field_aerpack_type']['widget'])  to debug data and you'll see #parents

see image:

image of debugging with dpm form to get parents of a field

With those data now you can do:

  $field_aerpack_type = $form_state->getValue(['field_aerial_detail', '0', 'subform', 'field_aerdet_package', '0', 'subform', 'field_aerpack_type']);
 

and access to taxonomy and get target_id

then we set this into $image where it does support image style and we use

  $response->addCommand(new HtmlCommand('.airpack-type-image', $image));
where we pass the image render to HtmlCommand which basically replaces the class previously defined .airpack-type-image

 

If any questions! let me know will be a pleasure!

Nivel