Allow to control autocomplete labels and values separaterely

Created on 9 August 2022, over 2 years ago
Updated 1 March 2024, 10 months ago

Problem/Motivation

The current autocompletion already supports separate label and value (\Drupal\Core\Entity\EntityAutocompleteMatcher::getMatches and renderItem() from autocomplete.es6.js). But it's not possible to alter or change it.

It is possible to provide custom @EntityReferenceSelection, but it only allows to return labels which is will be converted into values with ID appended by EntityAutocompleteMatcher::getMatches. The autocomplete widget even supports for HTML markup, which can be very handy sometimes, and it works with custom plugin, but it's not possible to control value in that case.

Sometimes it's requested by the client that they want to see some additional information during searching for something. For example, product variations (from Drupal Commerce) can have the same titles, but they have different SKU's.

The example above handled by custom @EntityReferenceSelection this is okay for label but weird for value:

Here are three problems:

  1. The value is overwhelmed by additional data which isn't required in the field itself, just in autocompletion.
  2. The value will be different after the page is reloaded. Because this is the responsibility of entity_autocomplete form element (\Drupal\Core\Entity\Element\EntityAutocomplete::getEntityLabels). This can confuse content editor that value is changed. But actually, it's the same, just visuals.
  3. If a widget or element uses autocreate feature ($element['#autocreate'], tags mode) it will lead to incorrectly named entities in result.

Proposed resolution

#1. Add support for array as a result for autocomplete plugins

The first and most easy, backward-compatible solution will be to support an array as result from \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface::getReferenceableEntities. This will require to change \Drupal\Core\Entity\EntityAutocompleteMatcher::getMatches.

Now:

      foreach ($entity_labels as $values) {
        foreach ($values as $entity_id => $label) {
          $key = "$label ($entity_id)";
          // Strip things like starting/trailing white spaces, line breaks and
          // tags.
          $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(Html::decodeEntities(strip_tags($key)))));
          // Names containing commas or quotes must be wrapped in quotes.
          $key = Tags::encode($key);
          $matches[] = ['value' => $key, 'label' => $label];
        }
      }

Possible changes:

      foreach ($entity_labels as $values) {
        foreach ($values as $entity_id => $result) {
          if (\is_array($result)) {
            [$value, $label] = $result;
          }
          else {
            $value = "$result ($entity_id)";
            $label = $result;
          }
          // Strip things like starting/trailing white spaces, line breaks and
          // tags.
          $value = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(Html::decodeEntities(strip_tags($value)))));
          // Names containing commas or quotes must be wrapped in quotes.
          $value = Tags::encode($value);
          $matches[] = ['value' => $value, 'label' => $label];
        }
      }

It's just a simple example to understand what I mean.

#2. Add ability to alter results

Add a custom event or alter hook for $matches.

P.s. I think this will be a good addition to use handlers not only for autocompletion itself but for \Drupal\Core\Entity\Element\EntityAutocomplete::getEntityLabels functionality. Because for now, if we want to change the value displayed after custom autocompletion, we have to create a custom form element and field widget that uses it or alter existing ones. It's obvious if @EntityReferenceSelection responsible for entity autocompletion, so it is also better to be responsible for value labels for its autocompletion used in form element. They are already working together, but missing this part.

Feature request
Status

Closed: won't fix

Version

11.0 🔥

Component
Entity 

Last updated about 20 hours ago

Created by

🇷🇺Russia niklan Russia, Perm

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024