Adicionando preenchimento automático para campo de texto

10

Eu tentei implementar um preenchimento automático no campo de texto para o drupal 8 no meu módulo personalizado

tudo o que eu queria era buscar e exibir o provável título digitado por meio do preenchimento automático, declarando uma função pública preenchida automaticamente dentro de uma classe em DefaultController.php no diretório de pastas -> 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);
    }
}

em seguida, criou um EditForm.php no diretório da pasta -> 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;
    }
}

também criou mymodule.routing.yml

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

ainda a funcionalidade de preenchimento automático não está sendo implementada? Alguém pode me dizer o que estou perdendo?

faça-me-vivo
fonte
você precisa passar parâmetros também drupal.org/node/2070985
Shreya Shetty
1
@ShreyaShetty Não, eu não preciso de parâmetros, pois no d7 eu teria usado '#autocomplete_path' => 'mymodule / autocomplete', então no d8 eu usei '#autocomplete_route_name' => 'mymodule.autocomplete', então nunca usei o parâmetro nem eu preciso fazer um ....
make-me-vivo

Respostas:

10

Sua classe precisa de alguma modificação, você precisa verificar a solicitação e colocá-la em $ 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
fonte
ele ainda não funcionou após buscar um pedido e colocá-lo em $ string
make-me-vivo
você verificou se o seu pedido foi impresso?
Vgoradiya
Eu acho \Drupal::entityQuery('node')que seria preferível usar além do select.
vgoradiya 5/05
Depois de assistir a guia Rede nas ferramentas de desenvolvimento do meu navegador, pude ver os resultados adequados na resposta, mas eles não estavam sendo mostrados na interface do usuário. Após algumas pesquisas, descobri que tinha um CSS personalizado configurando um z-indexelemento DOM que continha o formulário. O valor era muito alto e estava sobrepondo os resultados do preenchimento automático. Abaixar meu costume z-indexcorrigia isso para mim.
Tyler.frankenstein
11

Se você deseja selecionar uma entidade, existe uma maneira muito mais fácil de fazer isso. O Drupal 8 possui um tipo de campo padrão entity_autocomplete, basta especificar o seu elemento de formulário assim:

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

Consulte Campo de preenchimento automático personalizado para obter mais informações.

Além disso, nunca faça consultas ao banco de dados em tabelas de nó / entidade. Use \ Drupal :: entityQuery () para isso.

Berdir
fonte
Oi Berdir, Como obter dados da taxanomia no meu caso "cidade" usando o código acima, pois está funcionando perfeitamente para o nó, mas não para a taxanomia?
Sachin
5
  1. Crie um arquivo routing.yml e adicione o código abaixo: admin_example.autocomplete:

:

  path: '/admin_example/autocomplete'
  defaults:
    _controller: '\Drupal\admin_example\Controller\AdminNotesController::autocomplete'
  requirements:
    _permission: 'access content'
  1. O formulário que você criou no mymodule / src / Form / EditForm.php está correto

Você precisa alterar o código no controlador. O código está abaixo:

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
fonte
Olá Shreya, usei sua solução, mas em vez de ir para o formulário, ela está me dando o / p assim: [{"value": "1", "label": "Patel Residency"}, {"value": " 2 "," label ":" Jain Plaza "}, {" value ":" 3 "," label ":" Kanha Resort "}, {" value ":" 38 "," label ":" Hira Residency "} ] Eu quero que ele vá para o formulário eo campo deve funcionar como autocomplete
Sachin
2

Use o código @vgoradiya e, no loop foreach, tente da seguinte maneira:

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