3

I am creating a custom form where I have 2 fields.

  1. Taxonomy : select field having list of vocabularies.
  2. Terms : Autocomplete field having terms list.

When I start typing in terms field, the value of the term field is passed to the routing function. However I also need the value of the taxonomy field in routing function so that I can restrict the terms list.

Is there anyway that I can get the other field values in the routing function?

Here is my buildform function :

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['taxonomy'] = [
    '#type' => 'select',
    '#title' => $this->t('Select Taxonomy'),
    '#options' => $taxonomies,
  ];

  $form['taxonomy_terms'] = [
    '#type' => 'textfield',
    '#autocomplete_route_name' => 'unido_drupal_admin.get_taxonomies'
  ];

  return $form;
}

Here is my routing function :

public function get_taxonomies(Request $request) {
  // Here I need to get taxonomy field value to restrict the result.
  $params = $request->query->all();
  $result = \Drupal\taxonomy\Entity\Vocabulary::loadMultiple();
}

Thanks.

1 Answer 1

2

You need to define #autocomplete_route_parameters. I'm not sure if the form gets rebuilt during autocomplete queries (most likely not!) so you might need to define a #ajax on the vocabulary selector in order to rebuild the form and return the taxonomy_terms field with correct parameters set. This way you're defining a clear dependency, that field 2's available values depend on field 1's value. Below code is untested, but hopefully pushed you in the right direction:

public function buildForm(array $form, FormStateInterface $form_state) {
  $form['taxonomy'] = [
    '#type' => 'select',
    '#title' => $this->t('Select Taxonomy'),
    '#options' => $taxonomies,
    '#ajax' => [
      'callback' => 'Namespace\To\Your\Entity::vocabulary_callback',
      'event' => 'change',
      'wrapper' => 'term-wrapper'
    ],
  ];

  // Initially return a disabled field.
  $form['taxonomy_terms'] = [
    '#type' => 'textfield',
    '#disabled' => TRUE,
    '#prefix' => '<div id="term-wrapper">',
    '#suffix' => '</div>',
  ];

  // If someone's chosen a vocabulary, rewrite the field.
  if ($vid = $form_state->getValue('taxonomy', false)) {
    $form['taxonomy_terms'] = [
      '#type' => 'textfield',
      '#prefix' => '<div id="term-wrapper">',
      '#suffix' => '</div>',
      '#autocomplete_route_name' => 'unido_drupal_admin.get_taxonomies',
      '#autocomplete_route_parameters' => ['vid' => $vid],
    ];
  }

  return $form;
}

public function vocabulary_callback(array &$form, FormStateInterface $form_state) {
  return $form['taxonomy_terms'];
}

You also need to define this as a route parameter in your route's path element:

unido_drupal_admin.get_taxonomies:
  path: '/path/to/your/autocomplete/{vid}'

And also accept the parameter in your autocomplete function:

public function get_taxonomies(Request $request, $vid) {

There might be better ways to do this though, but with my limited D8 knowledge, this is how I'd approach it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.