2

I have a form that is inflated inside a box. In that form I have an autocomplete field. I want to allow the user, when they select an item from the autocomplete's suggestions they are automatically redirected to the appropriate page.

My current idea is to handle this in JS. But I don't like this as it makes it very difficult to use Drupal's routing system to route -- instead I have to hardcode things, which is bad.

class AutocompleteSearchForm extends FormBase {

  public function getFormId() {
    return 'search_form';
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['search'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Lookup'),
      '#description' => $this->t('Search.'),
      '#placeholder' => $this->t('Search'),
      '#autocomplete_route_name' => 'block.autocomplete.callback',
      '#autocomplete_route_parameters' => array('name' => 'name'),
      '#attached' => array(
        'library' => array('module/autocomplete'),
      ),
    );
    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    \Drupal::logger('module')->warning('form submitted for' . $form_state->get('search'));
  }
}

And my JS is:

(function ($) {
    $('#edit-search').on('autocompleteclose', function (event, node) {
        var entity_id = $(this).val();
        alert(entity_id);
    });
}(jQuery));

As you can see, I tried to manage this through the callback, but I don't expose a button and this doesn't submit unless the user hits the "enter" button, which isn't exactly intuitive.

Is JS the best way to handle this? If it is, is there a good way to get access to Drupal's path/router system from JS?

2 Answers 2

0

Try to use $build['#attached']['drupalSettings']['vartest'] = $test; to pass $test from PHP to JS. The variable $test contains the Drupal's path/routes.

Replace $build with the variable containing the form or the render array to which the settings are attached. In a form builder or hook_form_alter(), that would be $form.

0

No out-of-the-box feature in Drupal handles redirects directly after an autocomplete selection. However, the following approach, which does use a bit of JavaScript but also takes advantage of Drupal's routing system, might work for you:

In your JavaScript, you listen to the autocompleteclose event (as you are currently doing), but instead of trying to redirect immediately, you trigger form submission.

(function ($) {
    $('#edit-search').on('autocompleteclose', function (event, node) {
        $(this).closest('form').submit();
    });
}(jQuery));

In your submitForm function in PHP, you can handle the redirect using the form state setRedirect function, which does use Drupal routing system:

public function submitForm(array &$form, FormStateInterface $form_state) {
    $entity_id = $form_state->getValue('search');
    // Perform your logic to get the route name based on the entity id.
    $route_name = 'my_module.entity_view';  // Replace this with your logic.

    $form_state->setRedirect($route_name);
}

In the submitForm method above, you would replace 'my_module.entity_view' with the appropriate route name based on the entity id. If the entity id does not map directly to a route, you might need to load the entity, check its type or other properties, and determine the correct route based on that.

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.