diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml index df2a2fd02d..10c1bc948b 100644 --- a/core/config/schema/core.entity.schema.yml +++ b/core/config/schema/core.entity.schema.yml @@ -227,6 +227,9 @@ field.widget.settings.entity_reference_autocomplete_tags: match_operator: type: string label: 'Autocomplete matching' + match_size: + type: integer + label: 'Number of autocomplete suggestions.' size: type: integer label: 'Size of textfield' @@ -241,6 +244,9 @@ field.widget.settings.entity_reference_autocomplete: match_operator: type: string label: 'Autocomplete matching' + match_size: + type: integer + label: 'Number of autocomplete suggestions.' size: type: integer label: 'Size of textfield' diff --git a/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php b/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php index 2cede4dffa..7af0344217 100644 --- a/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php +++ b/core/lib/Drupal/Core/Entity/EntityAutocompleteMatcher.php @@ -61,7 +61,8 @@ public function getMatches($target_type, $selection_handler, $selection_settings if (isset($string)) { // Get an array of matching entities. $match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS'; - $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10); + $match_size = isset($selection_settings['match_size']) ? (int) $selection_settings['match_size'] : 10; + $entity_labels = $handler->getReferenceableEntities($string, $match_operator, $match_size); // Loop through the entities and convert them into autocomplete output. foreach ($entity_labels as $values) { diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php index 11f048e6f8..8b2f634728 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/EntityReferenceAutocompleteWidget.php @@ -28,6 +28,7 @@ class EntityReferenceAutocompleteWidget extends WidgetBase { public static function defaultSettings() { return [ 'match_operator' => 'CONTAINS', + 'match_size' => 10, 'size' => '60', 'placeholder' => '', ] + parent::defaultSettings(); @@ -44,6 +45,13 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#options' => $this->getMatchOperatorOptions(), '#description' => t('Select the method used to collect autocomplete suggestions. Note that Contains can cause performance issues on sites with thousands of entities.'), ]; + $element['match_size'] = [ + '#type' => 'number', + '#title' => t('Number of results'), + '#default_value' => $this->getSetting('match_size'), + '#min' => 0, + '#description' => t('The number of suggestions that will be listed. Use 0 to remove the limit.'), + ]; $element['size'] = [ '#type' => 'number', '#title' => t('Size of textfield'), @@ -68,6 +76,10 @@ public function settingsSummary() { $operators = $this->getMatchOperatorOptions(); $summary[] = t('Autocomplete matching: @match_operator', ['@match_operator' => $operators[$this->getSetting('match_operator')]]); + $match_size = $this->getSetting('match_size'); + if ($match_size != 0) { + $summary[] = t('Autocomplete suggestion list size: @size', ['@size' => $match_size]); + } $summary[] = t('Textfield size: @size', ['@size' => $this->getSetting('size')]); $placeholder = $this->getSetting('placeholder'); if (!empty($placeholder)) { @@ -88,7 +100,10 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $referenced_entities = $items->referencedEntities(); // Append the match operation to the selection settings. - $selection_settings = $this->getFieldSetting('handler_settings') + ['match_operator' => $this->getSetting('match_operator')]; + $selection_settings = $this->getFieldSetting('handler_settings') + [ + 'match_operator' => $this->getSetting('match_operator'), + 'match_size' => $this->getSetting('match_size'), + ]; $element += [ '#type' => 'entity_autocomplete', diff --git a/core/modules/entity_reference/entity_reference.install b/core/modules/entity_reference/entity_reference.install new file mode 100644 index 0000000000..3102be5055 --- /dev/null +++ b/core/modules/entity_reference/entity_reference.install @@ -0,0 +1,42 @@ +listAll('core.entity_form_display.') as $display_id) { + $display_config = $config->getEditable($display_id); + $display_data = $display_config->get(); + $save_display = FALSE; + + foreach ($display_data['content'] as $field_name => $widget_settings) { + // Deal only with entity reference autocomplete and descendants. + if (!empty($widget_settings['type'])) { + $plugin_definition = $field_widget_manager->getDefinition($widget_settings['type'], FALSE); + if (!empty($plugin_definition['class'])) { + if ($plugin_definition['class'] == EntityReferenceAutocompleteWidget::class || is_subclass_of($plugin_definition['class'], EntityReferenceAutocompleteWidget::class)) { + $widget_settings['settings']['match_size'] = 10; + $display_config->set('content.' . $field_name, $widget_settings); + $save_display = TRUE; + } + } + } + } + + if ($save_display) { + $display_config->save(TRUE); + } + } +} diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml index 9082f2d1bd..63ac5b4fb1 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.node.article.default.yml @@ -94,6 +94,7 @@ content: region: content settings: match_operator: CONTAINS + match_size: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml index 682f1a550c..eedced9da4 100644 --- a/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml +++ b/core/profiles/standard/config/install/core.entity_form_display.node.page.default.yml @@ -68,6 +68,7 @@ content: region: content settings: match_operator: CONTAINS + match_size: 10 size: 60 placeholder: '' third_party_settings: { } diff --git a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php index 511dee6e32..eea5d510c4 100644 --- a/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php +++ b/core/tests/Drupal/FunctionalJavascriptTests/EntityReference/EntityReferenceAutocompleteWidgetTest.php @@ -97,6 +97,30 @@ public function testEntityReferenceAutocompleteWidget() { $this->assertCount(1, $results); $assert_session->pageTextContains('Test page'); $assert_session->pageTextNotContains('Page test'); + + // Change the size of the result set. + entity_get_form_display('node', 'page', 'default') + ->setComponent($field_name, [ + 'type' => 'entity_reference_autocomplete', + 'settings' => [ + 'match_size' => 1, + ], + ]) + ->save(); + + $this->drupalGet('node/add/page'); + $page = $this->getSession()->getPage(); + + $autocomplete_field = $page->findField($field_name . '[0][target_id]'); + $autocomplete_field->setValue('Test'); + $this->getSession()->getDriver()->keyDown($autocomplete_field->getXpath(), ' '); + $assert_session->waitOnAutocomplete(); + + $results = $page->findAll('css', '.ui-autocomplete li'); + + $this->assertCount(1, $results); + $assert_session->pageTextContains('Test page'); + $assert_session->pageTextNotContains('Page test'); } }