为文本字段添加自动完成功能


10

我尝试在自定义模块中为drupal 8在文本字段中实现自动完成

我想要的只是获取并显示通过自动完成输入的可能标题,因此在文件夹目录-> mymodule / src / Controller / DefaultController.php中的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);
    }
}

然后在文件夹目录-> mymodule / src / Form / EditForm.php中创建一个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;
    }
}

还创建了mymodule.routing.yml

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

仍然无法实现自动完成功能?有人可以指出我在想什么吗?


您还需要传递参数drupal.org/node/2070985
Shreya Shetty

1
@ShreyaShetty不,我不需要参数,因为在d7中我会使用'#autocomplete_path'=>'mymodule / autocomplete',所以在d8中我使用了'#autocomplete_route_name'=>'mymodule.autocomplete',所以我从不使用参数我也不需要一个....
化妆我活

Answers:


10

您的班级需要一些修改,您需要检查请求并将其放入$ 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 '16

我认为\Drupal::entityQuery('node')最好将select分开使用。
vgoradiya's

在浏览器的开发工具中查看了“网络”选项卡之后,我可以在响应中看到正确的结果,但是未在UI中显示它们。经过一些挖掘,我发现我在z-index包含表单的DOM元素上设置了一些自定义css 。该值太高,与自动完成结果重叠。降低风俗习惯z-index对我来说是固定的。
tyler.frankenstein

11

如果要选择一个实体,那么有一种更简便的方法可以做到这一点。Drupal 8具有标准的entity_autocomplete字段类型,只需指定您的表单元素,如下所示:

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

有关更多信息,请参见自定义自动完成字段

同样,永远不要对节点/实体表进行数据库查询。为此使用\ Drupal :: entityQuery()。


嗨,Berdir,您好如何使用上述代码从我的案例“ city”中的分类中获取数据,因为它对于节点(而非分类)而言工作得很好?
萨钦

5
  1. 创建一个routing.yml文件并添加以下代码:admin_example.autocomplete:

  path: '/admin_example/autocomplete'
  defaults:
    _controller: '\Drupal\admin_example\Controller\AdminNotesController::autocomplete'
  requirements:
    _permission: 'access content'
  1. 您在mymodule / src / Form / EditForm.php中构建的表单是正确的

您需要在控制器中更改代码。代码如下:

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,我使用了您的解决方案,但没有像这样给我提供o / p的形式:[{“ value”:“ 1”,“ label”:“ Patel Residency”},{“ value”:“ 2“,” label“:” Jain Plaza“},{” value“:” 3“,” label“:” Kanha Resort“},{” value“:” 38“,” label“:” Hira Residency“} ]。我希望它转到表格,并且该字段应作为自动完成功能
-Sachin

2

使用@vgoradiya代码,然后在foreach循环上尝试这种方式:

    foreach ($result as $row)
    {
        $matches[] = ['value' => $row->nid, 'label' => check_plain($row->title)];
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.