Hướng dẫn tạo 1 field Autocomplete bằng cách dùng the Drupal 8 Form API

Hướng dẫn tạo 1 field Autocomplete bằng cách dùng the Drupal 8 Form API

In this article, I will not explain how to customise/alter an Autocomplete Field Widget — which should only be used on from using the Drupal Admin UI.

Here I will try to expose you a step by step guide which explains how you can create a custom Autocomplete field using the Drupal 8 Form API Core feature — An autocomplete that you could use in your own Drupal frontend applications.

>> Xử lý Ajax events trên entity reference (autocomplete) trong Drupal 8

>> Cải thiện performance trong Drupal 8 nhờ New Quicklink module

If you are looking for resources which explains how to implement Views to alter an Autocomplete Field

This is what you will be able to achieve at the end of this story

Truth can only be found in one place: the code
- Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship

Step 1- The autocomplete form element

The other day, I was asked to create a custom Autocomplete for a project which uses a custom Form build using the Drupal 8 Form API.

At first sight, you may be interested to use the #entity_autocomplete field type - it seems exactly what you need. Unfortunately, this is not. Indeed, the #entity_autocomplete doesn't allow you any customisation.

So, you will need the old folk’s #textfield and his cousin attribute #autocomplete_route_name

<?php

namespace Drupal\my_module\Form;

use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\Element\EntityAutocomplete;

/**
 * Form to handle article autocomplete.
 */
class ArticleAutocompleteForm extends FormBase {

  /**
   * The node storage.
   *
   * @var \Drupal\node\NodeStorage
   */
  protected $nodeStorage;

  /**
   * {@inheritdoc}
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->nodeStorage = $entity_type_manager->getStorage('node');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity_type.manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form['article'] = [
      '#type' => 'textfield',
      '#title' => $this->t('My Autocomplete'),
      '#autocomplete_route_name' => 'my_module.autocomplete.articles',
    ];

    $form['actions'] = ['#type' => 'actions'];
    $form['actions']['submit'] = [
      '#type' => 'submit',
      '#value' => $this->t('Save'),
    ];

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Extracts the entity ID from the autocompletion result.
    $article_id = EntityAutocomplete::extractEntityIdFromAutocompleteInput($form_state->getValue('article'));
  }
}

The #autocomplete_route_name attribute will allow you to define a route to handle the autocomplete business logic (data you will return given the user input).

You also may add the #autocomplete_route_parameters attribute, this one gives you the possibility to send a fixed unalterable parameter to your #autocomplete_route_name, you may use it to fix the number of results to return.

Step 2 — Define autocomplete route

Now you know how to create the autocomplete form, but you will need a route to manage the logic which will fetch data & return them.
How? By simply adding the reference to the route — where data will get retrieved from — to your my_module.routing.yml file:

my_module.autocomplete.articles:
  path: '/admin/my_module/autocomplete/articles'
  defaults:
    _controller: '\Drupal\my_module\Controller\ArticleAutoCompleteController::handleAutocomplete'
    _format: json
  requirements:

Be careful to use the same route name (here my_module.autocomplete.articles) in your previous #autocomplete_route_name.
Also, be sure to change permission according to your own needs.

Step 3 — Add Controller and return JSON response

Now having a routing & a form, you have to define your custom controller, with the handleAutocomplete method.
Well, it's precisely this method that makes sure that the proper data gets collected and properly formatted once requested by Drupal.

Let’s dig deeper and see how we can precisely deal with specific JSON response for our textfield element.

  1. Setup an ArticleAutoCompleteController class file under my_module/src/Controller/ArticleAutoCompleteController.php;
  2. Then, extend the ControllerBase class and setup your handle method (in our case ::handleAutocomplete see my_module.routing.yml);
<?phpnamespace Drupal\my_module\Controller;use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Entity\Element\EntityAutocomplete;/**
 * Defines a route controller for watches autocomplete form elements.
 */
class ArticleAutoCompleteController extends ControllerBase {/**
   * The node storage.
   *
   * @var \Drupal\node\NodeStorage
   */
  protected $nodeStorage;/**
   * {@inheritdoc}
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->nodeStroage = $entity_type_manager->getStorage('node');
  }/**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    // Instantiates this form class.
    return new static(
      $container->get('entity_type.manager')
    );
  }/**
   * Handler for autocomplete request.
   */
  public function handleAutocomplete(Request $request) {
    $results = [];
    $input = $request->query->get('q');// Get the typed string from the URL, if it exists.
    if (!$input) {
      return new JsonResponse($results);
    }$input = Xss::filter($input);$query = $this->nodeStroage->getQuery()
      ->condition('type', 'article')
      ->condition('title', $input, 'CONTAINS')
      ->groupBy('nid')
      ->sort('created', 'DESC')
      ->range(0, 10);$ids = $query->execute();
    $nodes = $ids ? $this->nodeStroage->loadMultiple($ids) : [];foreach ($nodes as $node) {
      switch ($node->isPublished()) {
        case TRUE:
          $availability = '';
          break;case FALSE:
        default:
          $availability = '';
          break;
      }$label = [
        $node->getTitle(),
        '<small>(' . $node->id() . ')</small>',
        $availability,
      ];$results[] = [
        'value' => EntityAutocomplete::getEntityLabels([$node]),
        'label' => implode(' ', $label),
      ];
    }return new JsonResponse($results);
  }
}

That’s pretty much all the hocus-pocus that you need to have an autocomplete based on a textfield of Drupal 8.

Bạn thấy bài viết này như thế nào?: 
Average: 5 (1 vote)
Ảnh của Tommy Tran

Tommy Tran owner Express Magazine

Drupal Developer having 9+ year experience, implementation and having strong knowledge of technical specifications, workflow development. Ability to perform effectively and efficiently in team and individually. Always enthusiastic and interseted to study new technologies

  • Skype ID: tthanhthuy
  • Phone/Zalo: (+84) 944 225 212
  • WhatsApp: (+84) 944 225 212
  • Line Messenger: (+84) 944 225 212
  • Email: [email protected]
  • Telegram Messenger: https:/t.me/tommytran0401

Quảng cáo việc làm

 

Thích hợp các bạn nữ mảng thợ may làm việc tại nước NGA

Đơn hàng Tuyển dụng 100 Thợ may đi Nga(đợt 1 tháng 3.2021, đợt 2 tháng 5.2021). Lương thực lãnh 800 USD, bao ăn ở, vé máy bay và visa, phí xuất cảnh(1800 USD)trả khi đi làm có lương. Bạn có thể liên hệ CÔNG TY qua Phone/Zalo: (+84) 944 225 212. Công ty sẽ tư vấn cho bạn.

Xem chi tiết: >>> https://bit.ly/3o9NOfR

Tìm kiếm bất động sản

 

Advertisement

 

jobsora

Dich vu khu trung tphcm

Dich vu diet chuot tphcm

Dich vu diet con trung

Quảng Cáo Bài Viết

 
Vì sao các bậc phụ huynh thích "soi" Facebook của bạn?

Vì sao các bậc phụ huynh thích "soi" Facebook của bạn?

Mong muốn sự an toàn và tâm lý tò mò trở thành 2 nguyên nhân hàng đầu.

Sử dụng git hiệu quả trong một dự án phần mềm, dự án Drupal

Sử dụng git hiệu quả trong một dự án phần mềm, dự án Drupal

Trong bài viết này mình sẽ nói về cách sử dụng git của mình trong thời gian qua.

Ứng dụng mới của Google+ - Nhận diện khuôn mặt

Ứng dụng mới của Google+ - Nhận diện khuôn mặt

Google đang “tung chiêu” liên tục để cạnh tranh với Facebook. Và một ứng dụng mới nhất của Google khiến người dùng “nức lòng” là “Find My Face” (Hãy tìm khuôn mặt của tôi)

Wordpress Freelancer

 

Wordpress Freelancer