Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Issue #3000623: Implement pagination for autocomplete requests #34

Open
wants to merge 14 commits into
base: 8.x-1.x
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions js/select2.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
}
return $.extend({}, params, {
q: params.term,
page: params.page || 1
selected: selected.filter(function (selected) {
return !selected.startsWith('$ID:');
})
Expand Down
15 changes: 14 additions & 1 deletion src/Controller/EntityAutocompleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,20 @@ public function handleAutocomplete(Request $request, $target_type, $selection_ha
// key/value store.
throw new AccessDeniedHttpException();
}
$matches['results'] = $this->matcher->getMatches($target_type, $selection_handler, $selection_settings, mb_strtolower($input), $request->query->get('selected', []));

$matches['results'] = $this->matcher->getMatches($target_type, $selection_handler, $selection_settings, mb_strtolower($input), $request->query->get('selected', []), $request->query->get('page') - 1);

// Remove reflection in Drupal 10.0.0.
$options = $selection_settings + [
'target_type' => $target_type,
'handler' => $selection_handler,
];
$handler = \Drupal::service('plugin.manager.entity_reference_selection')->getInstance($options);
$method = new \ReflectionMethod($handler, 'getReferenceableEntities');
$parameters = $method->getParameters();
if (count($parameters) > 3 && $parameters[3]->getName() === 'offset') {
$matches['pagination']['more'] = count($matches['results']) == 10;
}
}

return new JsonResponse($matches);
Expand Down
9 changes: 6 additions & 3 deletions src/EntityAutocompleteMatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public function __construct(SelectionPluginManagerInterface $selection_manager,
* (optional) The label of the entity to query by.
* @param array $selected
* (optional) An array of already selected items.
* @param int $page
* (optional) An offset for the results.
*
* @return array
* An array of matched entity labels, in the format required by the AJAX
Expand All @@ -61,7 +63,7 @@ public function __construct(SelectionPluginManagerInterface $selection_manager,
*
* @see \Drupal\system\Controller\EntityAutocompleteController
*/
public function getMatches($target_type, $selection_handler, array $selection_settings, $string = '', array $selected = []) {
public function getMatches($target_type, $selection_handler, array $selection_settings, $string = '', array $selected = [], $page = 0) {
$matches = [];

$options = $selection_settings + [
Expand All @@ -73,9 +75,10 @@ public function getMatches($target_type, $selection_handler, array $selection_se
if (isset($string)) {
// Get an array of matching entities.
$match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
$match_limit = isset($selection_settings['match_limit']) ? (int) $selection_settings['match_limit'] : 10;
$entity_labels = $handler->getReferenceableEntities($string, $match_operator, $match_limit + count($selected));

$match_limit = isset($selection_settings['match_limit']) ? (int) $selection_settings['match_limit'] : 10;
$entity_labels = $handler->getReferenceableEntities($string, $match_operator, $match_limit + count($selected), $page * 10);

// Loop through the entities and convert them into autocomplete output.
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
Expand Down