カスタムモジュールでdrupal 8のテキストフィールドにオートコンプリートを実装しようとしました
私が欲しかったのは、autocompleteを介して入力した可能性のあるタイトルを取得して表示することだけだったので、フォルダディレクトリ-> mymodule/src/Controller/DefaultController.phpのDefaultController.phpのクラス内でパブリック関数autocompleteを宣言しました
<?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);
}
}
次に、フォルダディレクトリにEditForm.phpを作成します-> 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;
}
}
mymodule.routing.ymlも作成しました
mymodule.autocomplete:
path: '/mymodule/autocomplete'
defaults:
_controller: '\Drupal\mymodule\Controller\DefaultController::autocomplete'
requirements:
_permission: 'access content'
まだオートコンプリート機能が実装されていませんか?誰かが私に何が欠けていることを指摘できますか?
クラスには、リクエストをチェックして$ 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);
}
}
エンティティを選択する場合は、それを行う簡単な方法があります。 Drupal 8には標準のentity_autocompleteフィールドタイプがあり、次のようにフォーム要素を指定するだけです:
$form['node'] = [
'#type' => 'entity_autocomplete',
'#target_type' => 'node',
];
詳細は カスタムオートコンプリートフィールド を参照してください。
また、ノード/エンティティテーブルに対してデータベースクエリを実行しないでください。そのためには、\ Drupal :: entityQuery()を使用します。
:
path: '/admin_example/autocomplete'
defaults:
_controller: '\Drupal\admin_example\Controller\AdminNotesController::autocomplete'
requirements:
_permission: 'access content'
コントローラのコードを変更する必要があります。コードは以下のとおりです。
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);
}
@vgoradiyaコードを使用してから、foreachループで次のように試してください。
foreach ($result as $row)
{
$matches[] = ['value' => $row->nid, 'label' => check_plain($row->title)];
}