web-dev-qa-db-fra.com

Comment ajouter la saisie semi-automatique à une zone de texte sur un formulaire?

Je voudrais ajouter une fonctionnalité de saisie semi-automatique à un élément de formulaire de zone de texte dans Drupal 8. J'ai un champ de texte personnalisé pleinement fonctionnel qui a la saisie semi-automatique fonctionnant sur le même formulaire. J'ai confirmé que le L'élément Textarea a la fonction processAutocomplete. Par conséquent, je ne sais pas pourquoi cela ne fonctionnerait pas.

Je me rends compte que l'ajout d'une saisie semi-automatique à une zone de texte est un peu peu orthodoxe, mais ce n'est pas la question. J'ai vu cela fait en Drupal 8, donc je sais que c'est possible. Je ne sais pas s'ils ont utilisé un formulaire pour l'accomplir.

J'ai ajouté le code approprié dans le fichier de routage:

my_module.autocomplete_name:
   path: '/my-module/test-autocomplete'
   defaults:
     _controller:'\Drupal\my_module\Controller\Controller::functionName'
     _format: json
   requirements:
     _access: 'TRUE'

J'ai également ajouté le champ de manière appropriée sur le formulaire:

$form['text_area'] = [
  '#type' => 'textarea',
  '#title' => t('Test text area'),
  '#default_value' => $authentication_configuration->get('text_area'),
  '#autocomplete_route_name' => 'my_module.autocomplete_name',
];

Enfin, j'ai la logique appropriée dans le contrôleur référencé:

public function testAutocomplete(request $request) {
  // Set up the array to be returned and get the user input
  $matches = array();
  $input = $request->query->get('q');
  // If there is user input
  if ($input) {
    $words = explode(' ', $input);
    foreach ($words as $Word) {
      /*
       * Logic for generating an autocomplete list of matches
       */
    }
  }
  return new JsonResponse($matches);
}
4
Travis

Les zones de texte ne prennent pas en charge la saisie semi-automatique prête à l'emploi, vous devez être un peu créatif pour le faire fonctionner.

Vous devez d'abord remplacer la méthode attach du comportement de saisie semi-automatique; ajoutez une bibliothèque avec un fichier JS contenant ceci:

(function ($) {
  Drupal.behaviors.autocomplete.attach = function attach(context) {
    var $autocomplete = $(context).find('input.form-autocomplete,textarea.form-autocomplete').once('autocomplete');
    if ($autocomplete.length) {
      var blacklist = $autocomplete.attr('data-autocomplete-first-character-blacklist');
      $.extend(Drupal.autocomplete.options, {
        firstCharacterBlacklist: blacklist || ''
      });

      $autocomplete.autocomplete(Drupal.autocomplete.options).each(function () {
        $(this).data('ui-autocomplete')._renderItem = Drupal.autocomplete.options.renderItem;
      });

      $autocomplete.on('compositionstart.autocomplete', function () {
        Drupal.autocomplete.options.isComposing = true;
      });
      $autocomplete.on('compositionend.autocomplete', function () {
        Drupal.autocomplete.options.isComposing = false;
      });
    }
  };
})(jQuery);

La fonction est une copie directe de la méthode de base attach, avec le textarea ajouté aux sélecteurs et quelques références modifiées.

Ensuite, vous devrez ajouter la méthode de processus de saisie semi-automatique à l'élément de formulaire (il n'y est pas par défaut), et référencer également votre bibliothèque:

use Drupal\Core\Render\Element\Textarea;

...

$form['text_area'] = [
  '#type' => 'textarea',
  '#title' => t('Test text area'),
  '#default_value' => $authentication_configuration->get('text_area'),
  '#autocomplete_route_name' => 'my_module.autocomplete_name',
  '#process' => [
    [Textarea::class, 'processAutocomplete'],
  ],
  '#attached' => [
    'library' => [
      'mymodule/autocomplete'
    ],
  ],
];

Videz le cache et vous devriez voir les résultats immédiatement.

6
Clive