Ajout de la saisie semi-automatique pour le champ de texte

10

J'ai essayé d'implémenter une saisie semi-automatique dans le champ de texte pour Drupal 8 dans mon module personnalisé

tout ce que je voulais, c'était récupérer et afficher le titre probable que j'avais tapé via la saisie semi-automatique afin de déclarer une fonction publique de saisie semi-automatique au sein d'une classe dans DefaultController.php dans le répertoire de dossiers -> mymodule / src / Controller / DefaultController.php

<?php

namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\JsonResponse;

class DefaultController extends ControllerBase
{
    public function autocomplete($string)
    {
        $matches = array();
        $db = \Drupal::database();
        $result = $db->select('node_field_data', 'n')
        ->fields('n', array('title', 'nid'))
        ->condition('title', '%'.db_like($string).'%', 'LIKE')
        ->addTag('node_access')
        ->execute();

        foreach ($result as $row) {
            $matches[$row->nid] = check_plain($row->title);
        }

        return new JsonResponse($matches);
    }
}

puis créé un EditForm.php dans le répertoire du dossier -> mymodule / src / Form / EditForm.php

<?php

namespace Drupal\mymodule\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

class EditForm extends FormBase
{
    public function getFormId()
    {
        return 'mymodule_edit_form';
    }

    public function buildForm(array $form, FormStateInterface $form_state)
    {
        $form = array();

  $form['input_fields']['nid'] = array(
    '#type' => 'textfield',
    '#title' => t('Name of the referenced node'),
    '#autocomplete_route_name' => 'mymodule.autocomplete',
    '#description' => t('Node Add/Edit type block'),
    '#default' => ($form_state->isValueEmpty('nid')) ? null : ($form_state->getValue('nid')),
    '#required' => true,
  );

        $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Create'),
  );

        return $form;
    }
}

a également créé mymodule.routing.yml

  mymodule.autocomplete:
  path: '/mymodule/autocomplete'
  defaults:
    _controller: '\Drupal\mymodule\Controller\DefaultController::autocomplete'
  requirements:
    _permission: 'access content'

la fonctionnalité de saisie semi-automatique n'est toujours pas implémentée? Quelqu'un peut-il me montrer ce qui me manque ??

fais-moi vivre
la source
vous devez également passer les paramètres drupal.org/node/2070985
Shreya Shetty
1
@ShreyaShetty Non, je n'ai pas besoin de paramètres car en d7 j'aurais utilisé '#autocomplete_path' => 'mymodule / autocomplete', donc en d8 j'ai utilisé '#autocomplete_route_name' => 'mymodule.autocomplete', donc je n'ai jamais utilisé de paramètre je n'en ai pas besoin non plus ...
fais-moi vivre

Réponses:

10

Votre classe a besoin de quelques modifications dont vous avez besoin pour vérifier la demande et la mettre dans $ string.

<?php

namespace Drupal\mymodule\Controller;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Component\Utility\Unicode;

class DefaultController extends ControllerBase
{

  /**
   * Returns response for the autocompletion.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The current request object containing the search string.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   A JSON response containing the autocomplete suggestions.
   */

  public function autocomplete(request $request) {
    $matches = array();
    $string = $request->query->get('q');
    if ($string) {
      $matches = array();
      $query = \Drupal::entityQuery('node')
      ->condition('status', 1)
      ->condition('title', '%'.db_like($string).'%', 'LIKE');
      //->condition('field_tags.entity.name', 'node_access');
      $nids = $query->execute();
      $result = entity_load_multiple('node', $nids);
      foreach ($result as $row) {
        //$matches[$row->nid->value] = $row->title->value;
        $matches[] = ['value' => $row->nid->value, 'label' => $row->title->value];
      }
    }
    return new JsonResponse($matches);
  }
}
vgoradiya
la source
il ne fonctionnait toujours pas après avoir récupéré une requête et l'avoir placée dans $ string
make-me-alive
avez-vous vérifié que votre demande était imprimée?
vgoradiya
Je pense \Drupal::entityQuery('node')qu'il serait préférable d'utiliser en dehors de sélectionner.
vgoradiya
Après avoir regardé l'onglet Réseau dans les outils de développement de mon navigateur, j'ai pu voir les résultats corrects dans la réponse, mais ils n'étaient pas affichés dans l'interface utilisateur. Après quelques recherches, j'ai trouvé que j'avais des paramètres CSS personnalisés définissant un z-indexélément DOM contenant le formulaire. La valeur était trop élevée et chevauchait les résultats de la saisie semi-automatique. Réduire ma coutume l'a z-indexcorrigé pour moi.
tyler.frankenstein
11

Si vous souhaitez sélectionner une entité, il existe un moyen plus simple de le faire. Drupal 8 a un type de champ standard entity_autocomplete, spécifiez simplement votre élément de formulaire comme ceci:

$form['node'] = [
  '#type' => 'entity_autocomplete',
  '#target_type' => 'node',
];

Voir Champ de saisie semi-automatique personnalisé pour plus d'informations.

En outre, ne faites jamais de requêtes de base de données sur des tables de nœuds / d'entités. Utilisez \ Drupal :: entityQuery () pour cela.

Berdir
la source
Salut Berdir, Comment obtenir des données de taxanomie dans mon cas "ville" en utilisant le code ci-dessus car cela fonctionne parfaitement pour le nœud mais pas pour la taxanomie ??
Sachin
5
  1. Créez un fichier routing.yml et ajoutez le code ci-dessous: admin_example.autocomplete:

:

  path: '/admin_example/autocomplete'
  defaults:
    _controller: '\Drupal\admin_example\Controller\AdminNotesController::autocomplete'
  requirements:
    _permission: 'access content'
  1. Le formulaire que vous avez créé dans mymodule / src / Form / EditForm.php est correct

Vous devez changer le code dans le contrôleur. Le code est ci-dessous:

public function autocomplete(Request $request)
{
 $string = $request->query->get('q');
    $matches = array();
      $query = db_select('node_field_data', 'n')
          ->fields('n', array('title', 'nid'))
          ->condition('title', $string . '%', 'LIKE')
          ->execute()
          ->fetchAll();
    foreach ($query as $row) {
        $matches[] = array('value' => $row->nid, 'label' => $row->title);
    }

    return new JsonResponse($matches);
}
Shreya Shetty
la source
Salut Shreya, j'ai utilisé votre solution mais au lieu d'aller au formulaire, elle me donne des o / p comme ceci: [{"value": "1", "label": "Patel Residency"}, {"value": " 2 "," label ":" Jain Plaza "}, {" value ":" 3 "," label ":" Kanha Resort "}, {" value ":" 38 "," label ":" Hira Residency "} ]. Je veux qu'il soit dans le formulaire et le champ devrait fonctionner comme saisie semi
Sachin
2

Utilisez le code @vgoradiya puis sur la boucle foreach essayez-le de cette façon:

    foreach ($result as $row)
    {
        $matches[] = ['value' => $row->nid, 'label' => check_plain($row->title)];
    }
Spencer Chang
la source