Подключение автодополнения к полю формы подробно описано здесь: http://niklan.net/blog/77
Однако есть момент, которого там не найти.
Если в форме есть несколько полей с однотипным алгоритмом автодополнения, но разными источниками хранения данных, не обязательно делать несколько отдельных функций автодополнения, в функцию автодополнения можно передать дополнительные параметры. В Drupal 7 можно было просто в hook_menu создать страницу с параметром. B варьировать этот параметр при создании формы, задавая #autocomplete_path.
function mymodule_menu() {
$items['autocomplete/%'] = array(
'page callback' => 'mymodule_autocomplete',
'page arguments' => array(1),
);
return $items;
}
function mymodule_myform() {
$form['myfield1'] = array(
'#type' => 'textfield',
'#title' => 'My field 1',
'#autocomplete_path' => 'autocomplete/myfield1',
);
$form['myfield2'] = array(
'#type' => 'textfield',
'#title' => 'My field 2',
'#autocomplete_path' => 'autocomplete/myfield2',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
}
function mymodule_autocomplete($string,$argument) {
switch($argument){
case 'myfield1':
$result = db_select('field1_table', 'n')
->fields('n', array('title'))
->condition('title', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute();
$matches = array();
foreach ($result as $row) {
$matches[$row->title] = check_plain($row->title);
}
break;
case 'myfield2':
$result = db_select('field2_table', 'n')
->fields('n', array('title'))
->condition('title', '%' . db_like($string) . '%', 'LIKE')
->range(0, 10)
->execute();
$matches = array();
foreach ($result as $row) {
$matches[$row->title] = check_plain($row->title);
}
break;
}
drupal_json_output($matches);
}
В Drupal 8 мы не можем задавать адрес страницы автодополнения напрямую, но используются два других параметра.
1. #autocomplete_route_name - название роута автодополнения
2. #autocomplete_route_parameters - массив с дополнительными параметрами
В итоге получаем следующий код.
В файле с роутами:
ceh.add_mat_autocomplete:
path: '/matac/{mtype}'
defaults:
_controller: '\Drupal\ceh\Controller\CehController::matac'
requirements:
_permission: 'view content'
В файле с формой:
$form['field1'] = [
'#type' => 'textfield',
'#title' => $this->t('Field1'),
'#autocomplete_route_name' => 'ceh.add_mat_autocomplete',
'#autocomplete_route_parameters' => array('mtype' => 'field1param'),
];
$form['field2'] = [
'#type' => 'textfield',
'#title' => $this->t('Field2'),
'#autocomplete_route_name' => 'ceh.add_mat_autocomplete',
'#autocomplete_route_parameters' => array('mtype' => 'field2param'),
];
В файле с контроллером роута:
public function matac(Request $request,$mtype){
$matches = array();
$string = $request->query->get('q');
if($string){
switch($mtype){
case 'field1param':
$query = Database::getConnection()->select('field1table', 'n')
->fields('n', array('nid', 'title'))
->condition('n.title', '%' . $string . '%', 'LIKE')
->range(0, 10);
$result = $query->execute();
foreach ($result as $row) {
$value = Html::escape($row->title . ' (' . $row->nid . ')');
$label = Html::escape($row->title);
$matches[] = ['value' => $value, 'label' => $label];
}
break;
case 'field2param':
$query = Database::getConnection()->select('field2table', 'n')
->fields('n', array('nid', 'title'))
->condition('n.title', '%' . $string . '%', 'LIKE')
->range(0, 10);
$result = $query->execute();
foreach ($result as $row) {
$value = Html::escape($row->title . ' (' . $row->nid . ')');
$label = Html::escape($row->title);
$matches[] = ['value' => $value, 'label' => $label];
}
break;
}
}
return new JsonResponse($matches);
}