How to pass current selection to entity browser select view I am using an Entity Browser (2.x-dev in Drupal 8) as form widget for a custom entity's entity reference base field. The entity browser is configured


as a modal display,
with single widget,
and no selection display,
using a view with entity browser bulk select field as widget, and
to append chosen entities to the current selection of the reference field.


Selecting the entities is working fine. But the entity reference field shall not have any duplicates.

In order to ease selecting of entities without duplicates, I'd like to filter already chosen entities from the entity browser view results. So users will see unselected entities only.

For this purpose, I created a custom views argument_default plugin that exposes the entity browser selection storage as context default argument for the entity ID:

&lt;?php

namespace Drupal\my_module\Plugin\views\argument_default;

use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * The entity browser selection argument default handler.
 *
 * @ViewsArgumentDefault(
 *   id = "entity_browser_selection",
 *   title = @Translation("Entity Browser Selection")
 * )
 */
class EntityBrowserSelection extends ArgumentDefaultPluginBase {

  /**
   * The selection storage.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
   */
  protected $selectionStorage;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, KeyValueStoreExpirableInterface $selection_storage) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this-&gt;selectionStorage = $selection_storage;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container-&gt;get('entity_browser.selection_storage')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function access() {
    return $this-&gt;view-&gt;getDisplay()-&gt;pluginId === 'entity_browser';
  }

  /**
   * {@inheritdoc}
   */
  public function getArgument() {
    $argument = NULL;
    $current_request = $this-&gt;view-&gt;getRequest();

    // Check if the widget context is available.
    if ($current_request-&gt;query-&gt;has('uuid')) {
      $uuid = $current_request-&gt;query-&gt;get('uuid');
      if ($storage = $this-&gt;selectionStorage-&gt;get($uuid)) {
        if (!empty($storage['selected_entities'])) {
          $argument = $storage['selected_entities'];
        }
      }
    }
    return $argument;
  }

}


The issue I face, is that the current selection within the selection storage is always empty, no matter how many entities have been selected at the entity reference field, and even after I complete the modal selection and open the entity browser again.

What do I have to do to have the current selection exposed in the entity browser's selection storage?
The Entity Browser doesn't current pass current default value items field in persistent data, but it's easy to add it.

1) Add persistent data using field_widget_form_alter()

/**
 * Implements hook_field_widget_form_alter().
 */
function mymodule_field_widget_form_alter(&amp;$element, FormStateInterface &amp;$form_state, $context) {
  if (!empty($element['entity_browser'])) {
    $default_value =  $element['entity_browser']['#default_value'];
    $ids = [];
    foreach ($default_value as $entity) {
      $ids[] = $entity-&gt;id();
    }
    $element['entity_browser']['#widget_context']['current_ids'] = implode('+', $ids);
  }
}


2) Update your selection so that if blank it shows all:

  /**
   * {@inheritdoc}
   */
  public function getArgument() {
    $argument = NULL;
    $current_request = $this-&gt;view-&gt;getRequest();

    // Check if the widget context is available.
    if ($current_request-&gt;query-&gt;has('uuid')) {
      $uuid = $current_request-&gt;query-&gt;get('uuid');
      if ($storage = $this-&gt;selectionStorage-&gt;get($uuid)) {
        if (!empty($storage['widget_context']['current_ids'])) {
          $argument = $storage['widget_context']['current_ids'];
        }
        else {
          $argument = 'all';
        }
      }
    }
    return $argument;
  }


3) Make sure you have "exclude" and "allow multiple" checked on your selection.



By the way, if you update to the latest dev release of entity_browser, you don't need your custom plugin.  There is a new entity_browser_widget_context default value views plugin that is configurable.

I also added an issue to the entity_browser queue to add this information when in the widget_context.