Hinzufügen der automatischen Vervollständigung für das Textfeld


10

Ich habe versucht, eine automatische Vervollständigung im Textfeld für Drupal 8 in meinem benutzerdefinierten Modul zu implementieren

Alles, was ich wollte, war, den wahrscheinlichen Titel abzurufen und anzuzeigen, den ich über Autocomplete eingegeben hatte, um eine öffentliche Funktion Autocomplete innerhalb einer Klasse in DefaultController.php im Ordnerverzeichnis -> mymodule / src / Controller / DefaultController.php zu deklarieren

<?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);
    }
}

Dann erstellte ich eine EditForm.php im Ordnerverzeichnis -> 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;
    }
}

hat auch mymodule.routing.yml erstellt

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

Wird die Autocomplete-Funktionalität immer noch nicht implementiert? Kann mir jemand zeigen, was ich vermisse?


Sie müssen Parameter auch drupal.org/node/2070985
Shreya Shetty

1
@ShreyaShetty Nein, ich brauche keine Parameter, da ich in d7 '#autocomplete_path' => 'mymodule / autocomplete' verwendet hätte, also habe ich in d8 '#autocomplete_route_name' => 'mymodule.autocomplete' verwendet, also habe ich nie Parameter verwendet Ich brauche auch keinen ...
mach mich lebendig

Antworten:


10

Ihre Klasse muss geändert werden. Sie müssen die Anforderung überprüfen und in $ string einfügen.

<?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);
  }
}

Es hat immer noch nicht funktioniert, nachdem eine Anfrage abgerufen und in $ string eingefügt wurde
mach mich lebendig

Haben Sie überprüft, ob Ihre Anfrage gedruckt wurde?
Vgoradiya

Ich denke, es \Drupal::entityQuery('node')wäre vorzuziehen, neben select zu verwenden.
Vgoradiya

Nachdem ich die Registerkarte "Netzwerk" in den Entwicklertools meines Browsers angesehen hatte, konnte ich in der Antwort die richtigen Ergebnisse sehen, die jedoch nicht in der Benutzeroberfläche angezeigt wurden. Nach einigem Graben stellte ich fest, dass ich eine benutzerdefinierte CSS-Einstellung z-indexfür ein DOM-Element hatte, das das Formular enthielt. Der Wert war zu hoch und überlappte die Ergebnisse der automatischen Vervollständigung. Das Absenken meines Brauchs hat z-indexes für mich behoben.
tyler.frankenstein

11

Wenn Sie eine Entität auswählen möchten, gibt es eine einfachere Möglichkeit, dies zu tun. Drupal 8 hat einen Standardfeldtyp entity_autocomplete. Geben Sie einfach Ihr Formularelement wie folgt an:

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

Sehen Sie die automatische Vervollständigung für benutzerdefiniertes Feld für weitere Informationen.

Führen Sie außerdem niemals Datenbankabfragen für Knoten- / Entitätstabellen durch. Verwenden Sie dazu \ Drupal :: entityQuery ().


Hallo Berdir, wie bekomme ich Daten aus der Taxanomie in meinem Fall "Stadt" mit dem obigen Code, da es für Knoten, aber nicht für Taxanomie einwandfrei funktioniert?
Sachin

5
  1. Erstellen Sie eine routing.yml-Datei und fügen Sie den folgenden Code hinzu: admin_example.autocomplete:

::

  path: '/admin_example/autocomplete'
  defaults:
    _controller: '\Drupal\admin_example\Controller\AdminNotesController::autocomplete'
  requirements:
    _permission: 'access content'
  1. Das Formular, das Sie in mymodule / src / Form / EditForm.php erstellt haben, ist korrekt

Sie müssen den Code in der Steuerung ändern. Der Code ist unten:

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);
}

Hallo Shreya, ich habe deine Lösung verwendet, aber anstatt zu dem Formular zu gehen, gibt es mir o / p wie folgt: [{"value": "1", "label": "Patel Residency"}, {"value": " 2 "," label ":" Jain Plaza "}, {" value ":" 3 "," label ":" Kanha Resort "}, {" value ":" 38 "," label ":" Hira Residency "} ]. Ich möchte, dass es zum Formular wechselt und das Feld als Autovervollständigung funktioniert
Sachin

2

Verwenden Sie den @ vgoradiya-Code und versuchen Sie es in der foreach-Schleife folgendermaßen:

    foreach ($result as $row)
    {
        $matches[] = ['value' => $row->nid, 'label' => check_plain($row->title)];
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.