diff --git a/config/schema/entity_browser.schema.yml b/config/schema/entity_browser.schema.yml
index 2f09d9f..7416799 100644
--- a/config/schema/entity_browser.schema.yml
+++ b/config/schema/entity_browser.schema.yml
@@ -108,6 +108,9 @@ entity_browser.browser.widget.view:
     submit_text:
       type: string
       label: 'Submit button text'
+    auto_select:
+      type: boolean
+      label: 'Automatically submit selection'
     view:
       type: string
       label: 'View ID'
diff --git a/entity_browser.libraries.yml b/entity_browser.libraries.yml
index 3141148..8448650 100644
--- a/entity_browser.libraries.yml
+++ b/entity_browser.libraries.yml
@@ -89,6 +89,7 @@ view:
 multi_step_display:
   version: VERSION
   js:
+    js/entity_browser.command_queue.js: {}
     js/entity_browser.multi_step_display.js: {}
   dependencies:
     - entity_browser/entity_list
diff --git a/js/entity_browser.command_queue.js b/js/entity_browser.command_queue.js
new file mode 100644
index 0000000..48c4287
--- /dev/null
+++ b/js/entity_browser.command_queue.js
@@ -0,0 +1,108 @@
+/**
+ * @file entity_browser.command_queue.js
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * Namespace for command queue functionality.
+   *
+   * Command queue provides functionality to queue ajax commands in front-end
+   * and execute them in one ajax request in backend. All commands triggered
+   * during ajax request execution, will be queue and executed after response
+   * from previous ajax request is received.
+   *
+   * @type {Object}
+   */
+  Drupal.entityBrowserCommandQueue = {};
+
+  /**
+   * Queue container for keeping commands for next queue execution. (protected)
+   *
+   * @type {Object}
+   */
+  var commandsQueue = {};
+
+  /**
+   * Registers behaviours related to Ajax commands execution.
+   */
+  Drupal.behaviors.entityBrowserCommandQueue = {
+    attach: function (context) {
+      var handler = $(context).find('[name="ajax_commands_handler"]');
+
+      handler.once('register-execute-commands')
+        .bind('execute-commands', Drupal.entityBrowserCommandQueue.executeCommands);
+    }
+  };
+
+  /**
+   * Action to queue command for future execution.
+   *
+   * @param {string} commandName
+   *   Command name, that will be executed.
+   * @param {Array} commandParam
+   *   Params for command. If command already exists in queue params will be
+   *   added to end of list.
+   */
+  Drupal.entityBrowserCommandQueue.queueCommand = function (commandName, commandParam) {
+    if (!commandsQueue[commandName]) {
+      commandsQueue[commandName] = [];
+    }
+
+    commandsQueue[commandName].push(commandParam);
+  };
+
+  /**
+   * Handler for executing queued commands over Ajax.
+   *
+   * @param {object} event
+   *   Event object.
+   * @param {boolean} addedCommand
+   *   Execution of queued commands is triggered after new command is added.
+   */
+  Drupal.entityBrowserCommandQueue.executeCommands = function (event, addedCommand) {
+    var handler = $(this);
+    var handlerElement = handler[0];
+    var runningAjax = Drupal.entityBrowserCommandQueue.isAjaxRunning(handlerElement, 'execute_js_commands');
+    var filledQueue = !$.isEmptyObject(commandsQueue);
+
+    if (!runningAjax && filledQueue) {
+      handler.val(JSON.stringify(commandsQueue));
+
+      // Clear Queue after command is set to handler element.
+      commandsQueue = {};
+
+      // Trigger event to execute event with defined command.
+      handler.trigger('execute_js_commands');
+    }
+    else if (!addedCommand && filledQueue) {
+      setTimeout($.proxy(Drupal.entityBrowserCommandQueue.executeCommands, handlerElement), 200);
+    }
+  };
+
+  /**
+   * Search is there current Ajax request executing for current event.
+   *
+   * @param {element} handlerElement
+   *   Element on what event is triggered.
+   * @param {string} eventName
+   *   Event name.
+   *
+   * @return {boolean}
+   *   Returns true if ajax event is still running for element.
+   */
+  Drupal.entityBrowserCommandQueue.isAjaxRunning = function (handlerElement, eventName) {
+    var ajax_list = Drupal.ajax.instances;
+
+    for (var i = 0; i < ajax_list.length; i++) {
+      if (ajax_list[i] && ajax_list[i].event === eventName && ajax_list[i].element === handlerElement && ajax_list[i].ajaxing) {
+        return true;
+      }
+    }
+
+    return false;
+  };
+
+}(jQuery, Drupal));
diff --git a/js/entity_browser.multi_step_display.js b/js/entity_browser.multi_step_display.js
index 2360f02..9fe1d9e 100644
--- a/js/entity_browser.multi_step_display.js
+++ b/js/entity_browser.multi_step_display.js
@@ -16,6 +16,24 @@
         stop: Drupal.entityBrowserMultiStepDisplay.entitiesReordered
       });
 
+      // Register add/remove entities event handlers.
+      $entities.once('register-add-entities')
+        .bind('add-entities', Drupal.entityBrowserMultiStepDisplay.addEntities);
+
+      $entities.once('register-remove-entities')
+        .bind('remove-entities', Drupal.entityBrowserMultiStepDisplay.removeEntities);
+
+      // Register event for remove button to use AJAX event.
+      var $remove_buttons = $entities.find('.entity-browser-remove-selected-entity');
+      $remove_buttons.once('register-click').on('click', function (event) {
+        event.preventDefault();
+
+        var button_element = $(event.target);
+        var remove_entity_id = button_element.attr('data-remove-entity') + '_' + button_element.attr('data-row-id');
+
+        $entities.trigger('remove-entities', [[remove_entity_id]]);
+      });
+
       // Add a toggle button for the display of selected entities.
       var $toggle = $('.entity-browser-show-selection');
 
@@ -27,12 +45,14 @@
         }
       }
 
-      $toggle.on('click', function (e) {
-        e.preventDefault();
-        $entities.slideToggle('fast', setToggleText);
-      });
+      if ($entities.length > 0) {
+        $toggle.once('register-click').on('click', function (e) {
+          e.preventDefault();
+          $entities.slideToggle('fast', setToggleText);
+        });
 
-      setToggleText();
+        setToggleText();
+      }
     }
   };
 
@@ -53,4 +73,67 @@
     }
   };
 
+  /**
+   * Remove entities from selection of multistep display.
+   *
+   * @param {object} event
+   *   Event object.
+   * @param {Array} entity_ids
+   *   Entity IDs that should be removed from selection.
+   */
+  Drupal.entityBrowserMultiStepDisplay.removeEntities = function (event, entity_ids) {
+    var entities_list = $(this);
+    var i;
+
+    for (i = 0; i < entity_ids.length; i++) {
+      // Remove dom element, and queue entity for removal in backend.
+      var element_selector = '[data-drupal-selector="edit-selected-'.concat(entity_ids[i].replace(/_/g, '-'), '"]');
+      entities_list.find(element_selector).remove();
+
+      Drupal.entityBrowserCommandQueue.queueCommand(
+        'remove',
+        {
+          entity_id: entity_ids[i]
+        }
+      );
+
+      // Remove action buttons, if there are no more entities selected.
+      if (entities_list.children().length === 0) {
+        entities_list.siblings('.entity-browser-use-selected').remove();
+        entities_list.siblings('.entity-browser-show-selection').remove();
+      }
+    }
+
+    entities_list.siblings('[name=ajax_commands_handler]').trigger('execute-commands', [true]);
+  };
+
+  /**
+   * Add entities into selection of multistep display.
+   *
+   * @param {object} event
+   *   Event object.
+   * @param {Array} entity_ids
+   *   Entity ID that should be added to selection.
+   */
+  Drupal.entityBrowserMultiStepDisplay.addEntities = function (event, entity_ids) {
+    var entities_list = $(this);
+    var i;
+
+    for (i = 0; i < entity_ids.length; i++) {
+      // Add proxy element that will be replaced with returned Ajax Command.
+      var proxy_element = $('<div></div>').uniqueId();
+      entities_list.append(proxy_element);
+
+      Drupal.entityBrowserCommandQueue.queueCommand(
+        'add',
+        {
+          entity_id: entity_ids[i],
+          proxy_id: proxy_element.attr('id')
+        }
+      );
+    }
+
+    entities_list.siblings('[name=ajax_commands_handler]').trigger('execute-commands', [true]);
+  };
+
 }(jQuery, Drupal));
diff --git a/js/entity_browser.view.js b/js/entity_browser.view.js
index a4f33ad..921bebd 100644
--- a/js/entity_browser.view.js
+++ b/js/entity_browser.view.js
@@ -47,6 +47,36 @@
             }
           });
         });
+
+        // If "auto_select" functionality is enabled, then selection column is
+        // hidden and click on row will actually add element into selection
+        // display over javascript event. Currently only multistep display
+        // supports that functionality.
+        if (drupalSettings.entity_browser_widget.auto_select) {
+          var selection_cells = views_instance.$view.find('.views-field-entity-browser-select');
+
+          // Register on cell parents (rows) click event.
+          selection_cells.parent()
+            .once('register-row-click')
+            .click(function (event) {
+              event.preventDefault();
+
+              var $row = $(this);
+
+              // Ensure to use input (checkbox) field from entity browser
+              // column dedicated for selection checkbox.
+              var $input = $row.find('.views-field-entity-browser-select input.form-checkbox');
+
+              // Get selection display element and trigger adding of entity
+              // over ajax request.
+              $row.parents('form')
+                .find('.entities-list')
+                .trigger('add-entities', [[$input.val()]]);
+            });
+
+          // Hide selection cells (selection column) with checkboxes.
+          selection_cells.hide();
+        }
       }
     }
   };
diff --git a/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php b/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
index 05676cf..90fe0b0 100644
--- a/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
+++ b/modules/entity_form/src/Plugin/EntityBrowser/Widget/EntityForm.php
@@ -21,7 +21,8 @@ use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
  * @EntityBrowserWidget(
  *   id = "entity_form",
  *   label = @Translation("Entity form"),
- *   description = @Translation("Provides entity form widget.")
+ *   description = @Translation("Provides entity form widget."),
+ *   autoSelect = FALSE
  * )
  */
 class EntityForm extends WidgetBase {
diff --git a/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml b/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
index 9dc617d..de7d83c 100644
--- a/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
+++ b/modules/example/config/install/core.entity_form_display.node.entity_browser_test.default.yml
@@ -5,6 +5,7 @@ dependencies:
     - field.field.node.entity_browser_test.body
     - field.field.node.entity_browser_test.field_files
     - field.field.node.entity_browser_test.field_files1
+    - field.field.node.entity_browser_test.field_files_over_ajax
     - field.field.node.entity_browser_test.field_image_browser
     - field.field.node.entity_browser_test.field_nodes
     - node.type.entity_browser_test
@@ -55,6 +56,18 @@ content:
       field_widget_edit: true
       field_widget_remove: true
     third_party_settings: {  }
+  field_files_over_ajax:
+    weight: 36
+    settings:
+      entity_browser: test_files_ajax
+      field_widget_display: label
+      field_widget_edit: true
+      field_widget_remove: true
+      selection_mode: selection_edit
+      open: false
+      field_widget_display_settings: {  }
+    third_party_settings: {  }
+    type: entity_browser_entity_reference
   field_image_browser:
     weight: 35
     settings:
diff --git a/modules/example/config/install/core.entity_view_display.node.entity_browser_test.default.yml b/modules/example/config/install/core.entity_view_display.node.entity_browser_test.default.yml
index 12bb96b..c4b8a3b 100644
--- a/modules/example/config/install/core.entity_view_display.node.entity_browser_test.default.yml
+++ b/modules/example/config/install/core.entity_view_display.node.entity_browser_test.default.yml
@@ -5,6 +5,7 @@ dependencies:
     - field.field.node.entity_browser_test.body
     - field.field.node.entity_browser_test.field_files
     - field.field.node.entity_browser_test.field_files1
+    - field.field.node.entity_browser_test.field_files_over_ajax
     - field.field.node.entity_browser_test.field_image_browser
     - field.field.node.entity_browser_test.field_nodes
     - node.type.entity_browser_test
@@ -40,6 +41,13 @@ content:
       link: true
     third_party_settings: {  }
     type: entity_reference_label
+  field_files_over_ajax:
+    weight: 106
+    label: above
+    settings:
+      link: true
+    third_party_settings: {  }
+    type: entity_reference_label
   field_image_browser:
     weight: 105
     label: above
diff --git a/modules/example/config/install/entity_browser.browser.test_files_ajax.yml b/modules/example/config/install/entity_browser.browser.test_files_ajax.yml
new file mode 100644
index 0000000..5b7e81a
--- /dev/null
+++ b/modules/example/config/install/entity_browser.browser.test_files_ajax.yml
@@ -0,0 +1,44 @@
+langcode: und
+status: true
+dependencies:
+  enforced:
+    module:
+      - entity_browser_example
+  module:
+    - views
+name: test_files_ajax
+label: 'Test entity browser for files (with auto loading)'
+display: iframe
+display_configuration:
+  width: '650'
+  height: '500'
+  link_text: 'Select entities'
+  auto_open: false
+selection_display: multi_step_display
+selection_display_configuration:
+  entity_type: node
+  display: label
+  display_settings: {  }
+  select_text: 'Use selected'
+  selection_hidden: false
+widget_selector: tabs
+widget_selector_configuration: {  }
+widgets:
+  a4ad947c-9669-497c-9988-24351955a02f:
+    settings:
+      view: files_entity_browser
+      view_display: entity_browser_1
+      submit_text: 'Select entities'
+      auto_select: true
+    uuid: a4ad947c-9669-497c-9988-24351955a02f
+    weight: -10
+    label: 'Files listing'
+    id: view
+  735d146c-a4b2-4327-a057-d109e0905e05:
+    settings:
+      upload_location: 'public://'
+      submit_text: 'Select files'
+    uuid: 735d146c-a4b2-4327-a057-d109e0905e05
+    weight: -9
+    label: 'Upload files'
+    id: upload
diff --git a/modules/example/config/install/field.field.node.entity_browser_test.field_files_over_ajax.yml b/modules/example/config/install/field.field.node.entity_browser_test.field_files_over_ajax.yml
new file mode 100644
index 0000000..291ad83
--- /dev/null
+++ b/modules/example/config/install/field.field.node.entity_browser_test.field_files_over_ajax.yml
@@ -0,0 +1,24 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.node.field_files_over_ajax
+    - node.type.entity_browser_test
+id: node.entity_browser_test.field_files_over_ajax
+field_name: field_files_over_ajax
+entity_type: node
+bundle: entity_browser_test
+label: 'Files (with auto loading)'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  handler: 'default:file'
+  handler_settings:
+    target_bundles: null
+    sort:
+      field: _none
+    auto_create: false
+field_type: entity_reference
diff --git a/modules/example/config/install/field.storage.node.field_files_over_ajax.yml b/modules/example/config/install/field.storage.node.field_files_over_ajax.yml
new file mode 100644
index 0000000..bb8a800
--- /dev/null
+++ b/modules/example/config/install/field.storage.node.field_files_over_ajax.yml
@@ -0,0 +1,19 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - file
+    - node
+id: node.field_files_over_ajax
+field_name: field_files_over_ajax
+entity_type: node
+type: entity_reference
+settings:
+  target_type: file
+module: core
+locked: false
+cardinality: -1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/src/Annotation/EntityBrowserSelectionDisplay.php b/src/Annotation/EntityBrowserSelectionDisplay.php
index f55babb..a729234 100644
--- a/src/Annotation/EntityBrowserSelectionDisplay.php
+++ b/src/Annotation/EntityBrowserSelectionDisplay.php
@@ -50,4 +50,16 @@ class EntityBrowserSelectionDisplay extends Plugin {
    */
   public $acceptPreselection = FALSE;
 
+  /**
+   * Indicates that javascript commands can be executed for Selection display.
+   *
+   * Currently supported javascript commands are adding and removing selection
+   * from selection display. Javascript commands use Ajax requests to load
+   * relevant changes and makes user experience way better, becase form is not
+   * flashed every time.
+   *
+   * @var bool
+   */
+  public $jsCommands = FALSE;
+
 }
diff --git a/src/Annotation/EntityBrowserWidget.php b/src/Annotation/EntityBrowserWidget.php
index c192ee0..d8a512e 100644
--- a/src/Annotation/EntityBrowserWidget.php
+++ b/src/Annotation/EntityBrowserWidget.php
@@ -40,4 +40,11 @@ class EntityBrowserWidget extends Plugin {
    */
   public $description = '';
 
+  /**
+   * Indicates that widget supports auto selection of entities.
+   *
+   * @var bool
+   */
+  public $autoSelect = FALSE;
+
 }
diff --git a/src/Form/EntityBrowserForm.php b/src/Form/EntityBrowserForm.php
index f2735a0..8f3c1e2 100644
--- a/src/Form/EntityBrowserForm.php
+++ b/src/Form/EntityBrowserForm.php
@@ -3,6 +3,7 @@
 namespace Drupal\entity_browser\Form;
 
 use Drupal\Component\Uuid\UuidInterface;
+use Drupal\Core\Config\ConfigException;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
@@ -111,6 +112,8 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
       $this->init($form_state);
     }
 
+    $this->isFunctionalForm();
+
     $form['#attributes']['class'][] = 'entity-browser-form';
     if (!empty($form_state->get(['entity_browser', 'instance_uuid']))) {
       $form['#attributes']['data-entity-browser-uuid'] = $form_state->get(['entity_browser', 'instance_uuid']);
@@ -145,6 +148,21 @@ class EntityBrowserForm extends FormBase implements EntityBrowserFormInterface {
   }
 
   /**
+   * Check if entity browser with selected configuration combination can work.
+   */
+  protected function isFunctionalForm() {
+    /** @var \Drupal\entity_browser\WidgetInterface $widget */
+    foreach ($this->entityBrowser->getWidgets() as $widget) {
+      /** @var \Drupal\entity_browser\SelectionDisplayInterface $selectionDisplay */
+      $selectionDisplay = $this->entityBrowser->getSelectionDisplay();
+
+      if ($widget->requiresJsCommands() && !$selectionDisplay->supportsJsCommands()) {
+        throw new ConfigException('Used entity browser selection display cannot work in combination with settings defined for used selection widget.');
+      }
+    }
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
diff --git a/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php b/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php
index 97ac5a7..b943143 100644
--- a/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php
+++ b/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php
@@ -2,6 +2,10 @@
 
 namespace Drupal\entity_browser\Plugin\EntityBrowser\SelectionDisplay;
 
+use Drupal\Core\Ajax\AfterCommand;
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\InvokeCommand;
+use Drupal\Core\Ajax\ReplaceCommand;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\entity_browser\FieldWidgetDisplayManager;
@@ -16,7 +20,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  *   id = "multi_step_display",
  *   label = @Translation("Multi step selection display"),
  *   description = @Translation("Shows the current selection display, allowing to mix elements selected through different widgets in several steps."),
- *   acceptPreselection = TRUE
+ *   acceptPreselection = TRUE,
+ *   jsCommands = TRUE
  * )
  */
 class MultiStepDisplay extends SelectionDisplayBase {
@@ -80,6 +85,12 @@ class MultiStepDisplay extends SelectionDisplayBase {
    * {@inheritdoc}
    */
   public function getForm(array &$original_form, FormStateInterface $form_state) {
+
+    // Check if trigger element is dedicated to handle front-end commands.
+    if (($triggering_element = $form_state->getTriggeringElement()) && $triggering_element['#name'] === 'ajax_commands_handler' && !empty($triggering_element['#value'])) {
+      $this->executeJsCommand($form_state);
+    }
+
     $selected_entities = $form_state->get(['entity_browser', 'selected_entities']);
 
     $form = [];
@@ -115,6 +126,7 @@ class MultiStepDisplay extends SelectionDisplayBase {
           '#submit' => [[get_class($this), 'removeItemSubmit']],
           '#name' => 'remove_' . $entity->id() . '_' . $id,
           '#attributes' => [
+            'class' => ['entity-browser-remove-selected-entity'],
             'data-row-id' => $id,
             'data-remove-entity' => 'items_' . $entity->id(),
           ],
@@ -126,12 +138,33 @@ class MultiStepDisplay extends SelectionDisplayBase {
         ],
       ];
     }
+
+    // Add hidden element used to make execution of front-end commands.
+    $form['ajax_commands_handler'] = [
+      '#type' => 'hidden',
+      '#name' => 'ajax_commands_handler',
+      '#id' => 'ajax_commands_handler',
+      '#attributes' => ['id' => 'ajax_commands_handler'],
+      '#ajax' => [
+        'callback' => [get_class($this), 'handleAjaxCommand'],
+        'wrapper' => 'edit-selected',
+        'event' => 'execute_js_commands',
+        'progress' => [
+          'type' => 'fullscreen',
+        ],
+      ],
+    ];
+
     $form['use_selected'] = [
       '#type' => 'submit',
       '#value' => $this->t($this->configuration['select_text']),
       '#name' => 'use_selected',
+      '#attributes' => [
+        'class' => ['entity-browser-use-selected'],
+      ],
       '#access' => empty($selected_entities) ? FALSE : TRUE,
     ];
+
     $form['show_selection'] = [
       '#type' => 'button',
       '#value' => $this->t('Show selected'),
@@ -145,6 +178,182 @@ class MultiStepDisplay extends SelectionDisplayBase {
   }
 
   /**
+   * Execute command generated by front-end.
+   *
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   Form state object.
+   */
+  protected function executeJsCommand(FormStateInterface $form_state) {
+    $triggering_element = $form_state->getTriggeringElement();
+
+    $commands = json_decode($triggering_element['#value'], TRUE);
+
+    // Process Remove command.
+    if (isset($commands['remove'])) {
+      $entity_ids = $commands['remove'];
+
+      // Remove weight of entity being removed.
+      foreach ($entity_ids as $entity_info) {
+        $entity_id_info = explode('_', $entity_info['entity_id']);
+
+        $form_state->unsetValue([
+          'selected',
+          $entity_info['entity_id'],
+        ]);
+
+        // Remove entity itself.
+        $selected_entities = &$form_state->get(['entity_browser', 'selected_entities']);
+        unset($selected_entities[$entity_id_info[2]]);
+      }
+
+      static::saveNewOrder($form_state);
+    }
+
+    // Process Add command.
+    if (isset($commands['add'])) {
+      $entity_ids = $commands['add'];
+
+      $entities_to_add = [];
+      $added_entities = [];
+
+      // Generate list of entities grouped by type, to speed up loadMultiple.
+      foreach ($entity_ids as $entity_pair_info) {
+        $entity_info = explode(':', $entity_pair_info['entity_id']);
+
+        if (!isset($entities_to_add[$entity_info[0]])) {
+          $entities_to_add[$entity_info[0]] = [];
+        }
+
+        $entities_to_add[$entity_info[0]][] = $entity_info[1];
+      }
+
+      // Load Entities and add into $added_entities, so that we have list of
+      // entities with key - "type:id".
+      foreach ($entities_to_add as $entity_type => $entity_type_ids) {
+        $indexed_entities = $this->entityTypeManager->getStorage($entity_type)
+          ->loadMultiple($entity_type_ids);
+
+        foreach ($indexed_entities as $entity_id => $entity) {
+          $added_entities[implode(':', [
+            $entity_type,
+            $entity_id,
+          ])] = $entity;
+        }
+      }
+
+      // Array is accessed as reference, so that changes are propagated.
+      $selected_entities = &$form_state->get([
+        'entity_browser',
+        'selected_entities',
+      ]);
+
+      // Fill list of selected entities in correct order with loaded entities.
+      // In this case, order is preserved and multiple entities with same ID
+      // can be selected properly.
+      foreach ($entity_ids as $entity_pair_info) {
+        $selected_entities[] = $added_entities[$entity_pair_info['entity_id']];
+      }
+    }
+  }
+
+  /**
+   * Handler to generate Ajax response, after command is executed.
+   *
+   * @param array $form
+   *   Form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   Form state object.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   Return Ajax response with commands.
+   */
+  public static function handleAjaxCommand(array $form, FormStateInterface $form_state) {
+    $ajax = new AjaxResponse();
+
+    if (($triggering_element = $form_state->getTriggeringElement()) && $triggering_element['#name'] === 'ajax_commands_handler' && !empty($triggering_element['#value'])) {
+      $commands = json_decode($triggering_element['#value'], TRUE);
+
+      // Entity IDs that are affected by this command.
+      if (isset($commands['add'])) {
+        /** @var \Drupal\Core\Render\RendererInterface $renderer */
+        $renderer = \Drupal::service('renderer');
+        $entity_ids = $commands['add'];
+
+        $selected_entities = &$form_state->get([
+          'entity_browser',
+          'selected_entities',
+        ]);
+
+        // Get entities added by this command and generate JS commands for them.
+        $selected_entity_keys = array_keys($selected_entities);
+        $key_index = count($selected_entity_keys) - count($entity_ids);
+        foreach ($entity_ids as $entity_pair_info) {
+          $last_entity_id = $selected_entities[$selected_entity_keys[$key_index]]->id();
+
+          $html = $renderer->render($form['selection_display']['selected']['items_' . $last_entity_id . '_' . $selected_entity_keys[$key_index]]);
+
+          $ajax->addCommand(
+            new ReplaceCommand('div[id="' . $entity_pair_info['proxy_id'] . '"]', static::trimSingleHtmlTag($html))
+          );
+
+          $key_index++;
+        }
+
+        // Check if action buttons should be added to form. When number of added
+        // entities is equal to number of selected entities. Then form buttons
+        // should be also rendered: use_selected and show_selection.
+        if (count($selected_entities) === count($entity_ids)) {
+
+          // Order is important, since commands are executed one after another.
+          $ajax->addCommand(
+            new AfterCommand('.entities-list', static::trimSingleHtmlTag($renderer->render($form['selection_display']['show_selection'])))
+          );
+
+          $ajax->addCommand(
+            new AfterCommand('.entities-list', static::trimSingleHtmlTag($renderer->render($form['selection_display']['use_selected'])))
+          );
+        }
+      }
+
+      // Add Invoke command to trigger loading of entities that are queued
+      // during execution of current Ajax request.
+      $ajax->addCommand(
+        new InvokeCommand('[name=ajax_commands_handler]', 'trigger', ['execute-commands'])
+      );
+    }
+
+    return $ajax;
+  }
+
+  /**
+   * Make HTML with single tag suitable for Ajax response.
+   *
+   * Comments will be removed and also whitespace characters, because Ajax JS
+   * "insert" command handling checks number of base elements in response and
+   * wraps it in a "div" tag if there are more then one base element.
+   *
+   * @param string $html
+   *   HTML content.
+   *
+   * @return string
+   *   Returns cleaner HTML content, suitable for Ajax responses.
+   */
+  protected static function trimSingleHtmlTag($html) {
+    $clearHtml = trim($html);
+
+    // Remove comments around main single HTML tag. RegEx flag 's' is there to
+    // allow matching on whitespaces too. That's needed, because generated HTML
+    // contains a lot newlines.
+    if (preg_match_all('/(<(?!(!--)).+((\\/)|(<\\/[a-z]+))>)/is', $clearHtml, $matches)) {
+      if (!empty($matches) && !empty($matches[0])) {
+        $clearHtml = $matches[0][0];
+      }
+    }
+
+    return $clearHtml;
+  }
+
+  /**
    * Submit callback for remove buttons.
    *
    * @param array $form
diff --git a/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php b/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php
index 05d8843..6d9f914 100644
--- a/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php
+++ b/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php
@@ -12,7 +12,8 @@ use Drupal\entity_browser\SelectionDisplayBase;
  *   id = "no_display",
  *   label = @Translation("No selection display"),
  *   description = @Translation("Skips the current selection display and immediately delivers the entities selected."),
- *   acceptPreselection = FALSE
+ *   acceptPreselection = FALSE,
+ *   jsCommands = FALSE
  * )
  */
 class NoDisplay extends SelectionDisplayBase {
diff --git a/src/Plugin/EntityBrowser/SelectionDisplay/View.php b/src/Plugin/EntityBrowser/SelectionDisplay/View.php
index d13dff5..8001cda 100644
--- a/src/Plugin/EntityBrowser/SelectionDisplay/View.php
+++ b/src/Plugin/EntityBrowser/SelectionDisplay/View.php
@@ -14,7 +14,8 @@ use Drupal\views\Views;
  *   id = "view",
  *   label = @Translation("View selection display"),
  *   description = @Translation("Use a pre-configured view as selection area."),
- *   acceptPreselection = TRUE
+ *   acceptPreselection = TRUE,
+ *   jsCommands = FALSE
  * )
  */
 class View extends SelectionDisplayBase {
diff --git a/src/Plugin/EntityBrowser/Widget/Upload.php b/src/Plugin/EntityBrowser/Widget/Upload.php
index e05e9a2..c031749 100644
--- a/src/Plugin/EntityBrowser/Widget/Upload.php
+++ b/src/Plugin/EntityBrowser/Widget/Upload.php
@@ -19,7 +19,8 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  * @EntityBrowserWidget(
  *   id = "upload",
  *   label = @Translation("Upload"),
- *   description = @Translation("Adds an upload field browser's widget.")
+ *   description = @Translation("Adds an upload field browser's widget."),
+ *   autoSelect = FALSE
  * )
  */
 class Upload extends WidgetBase {
@@ -162,6 +163,8 @@ class Upload extends WidgetBase {
    * {@inheritdoc}
    */
   public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
     $form['upload_location'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Upload location'),
@@ -182,12 +185,6 @@ class Upload extends WidgetBase {
       '#required' => TRUE,
     ];
 
-    $form['submit_text'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Submit button text'),
-      '#default_value' => $this->configuration['submit_text'],
-    ];
-
     if ($this->moduleHandler->moduleExists('token')) {
       $form['token_help'] = [
         '#theme' => 'token_tree_link',
diff --git a/src/Plugin/EntityBrowser/Widget/View.php b/src/Plugin/EntityBrowser/Widget/View.php
index 8e78276..1d561d8 100644
--- a/src/Plugin/EntityBrowser/Widget/View.php
+++ b/src/Plugin/EntityBrowser/Widget/View.php
@@ -22,7 +22,8 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
  *   id = "view",
  *   label = @Translation("View"),
  *   provider = "views",
- *   description = @Translation("Uses a view to provide entity listing in a browser's widget.")
+ *   description = @Translation("Uses a view to provide entity listing in a browser's widget."),
+ *   autoSelect = TRUE
  * )
  */
 class View extends WidgetBase implements ContainerFactoryPluginInterface {
@@ -257,6 +258,7 @@ class View extends WidgetBase implements ContainerFactoryPluginInterface {
   public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
     $values = $form_state->getValues()['table'][$this->uuid()]['form'];
     $this->configuration['submit_text'] = $values['submit_text'];
+    $this->configuration['auto_select'] = $values['auto_select'];
     if (!empty($values['view'])) {
       list($view_id, $display_id) = explode('.', $values['view']);
       $this->configuration['view'] = $view_id;
diff --git a/src/SelectionDisplayBase.php b/src/SelectionDisplayBase.php
index b91c79d..218bd94 100644
--- a/src/SelectionDisplayBase.php
+++ b/src/SelectionDisplayBase.php
@@ -132,6 +132,13 @@ abstract class SelectionDisplayBase extends PluginBase implements SelectionDispl
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function supportsJsCommands() {
+    return $this->getPluginDefinition()['jsCommands'];
+  }
+
+  /**
    * Marks selection as done - sets value in form state and dispatches event.
    */
   protected function selectionDone(FormStateInterface $form_state) {
diff --git a/src/SelectionDisplayInterface.php b/src/SelectionDisplayInterface.php
index a072a52..84e1564 100644
--- a/src/SelectionDisplayInterface.php
+++ b/src/SelectionDisplayInterface.php
@@ -69,4 +69,12 @@ interface SelectionDisplayInterface extends PluginInspectionInterface, Configura
    */
   public function checkPreselectionSupport();
 
+  /**
+   * Returns true if selection display supports selection over javascript.
+   *
+   * @return bool
+   *   True if javascript add/remove events are supported.
+   */
+  public function supportsJsCommands();
+
 }
diff --git a/src/Tests/ConfigUITest.php b/src/Tests/ConfigUITest.php
index 3ddeceb..da58a79 100644
--- a/src/Tests/ConfigUITest.php
+++ b/src/Tests/ConfigUITest.php
@@ -218,7 +218,12 @@ class ConfigUITest extends WebTestBase {
     $this->assertEqual('entity_form', $widget->id(), 'Entity browser widget was correctly saved.');
     $this->assertEqual($second_uuid, $widget->uuid(), 'Entity browser widget uuid was correctly saved.');
     $configuration = $widget->getConfiguration()['settings'];
-    $this->assertEqual(['entity_type' => 'user', 'bundle' => 'user', 'form_mode' => 'register', 'submit_text' => 'But some are more equal than others'], $configuration, 'Entity browser widget configuration was correctly saved.');
+    $this->assertEqual([
+      'entity_type' => 'user',
+      'bundle' => 'user',
+      'form_mode' => 'register',
+      'submit_text' => 'But some are more equal than others',
+    ], $configuration, 'Entity browser widget configuration was correctly saved.');
     $this->assertEqual(2, $widget->getWeight(), 'Entity browser widget weight was correctly saved.');
 
     // Navigate to edit.
diff --git a/src/WidgetBase.php b/src/WidgetBase.php
index d4b9b94..704742a 100644
--- a/src/WidgetBase.php
+++ b/src/WidgetBase.php
@@ -109,6 +109,8 @@ abstract class WidgetBase extends PluginBase implements WidgetInterface, Contain
    * {@inheritdoc}
    */
   public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) {
+    $form = [];
+
     // Allow configuration overrides at runtime based on form state to enable
     // use cases where the instance of a widget may have contextual
     // configuration like field settings. "widget_context" doesn't have to be
@@ -120,30 +122,46 @@ abstract class WidgetBase extends PluginBase implements WidgetInterface, Contain
       }
     }
 
-    $form['actions'] = [
-      '#type' => 'actions',
-      'submit' => [
-        '#type' => 'submit',
-        '#value' => $this->configuration['submit_text'],
-        '#eb_widget_main_submit' => TRUE,
-        '#attributes' => ['class' => ['is-entity-browser-submit']],
-        '#button_type' => 'primary',
-      ],
-    ];
+    // Check if widget supports auto select functionality and expose config to
+    // front-end javascript.
+    $autoSelect = FALSE;
+    if ($this->getPluginDefinition()['autoSelect']) {
+      $autoSelect = $this->configuration['auto_select'];
+      $form['#attached']['drupalSettings']['entity_browser_widget']['auto_select'] = $autoSelect;
+    }
+
+    // In case of auto select, widget will handle adding entities in JS.
+    if (!$autoSelect) {
+      $form['actions'] = [
+        '#type' => 'actions',
+        'submit' => [
+          '#type' => 'submit',
+          '#value' => $this->configuration['submit_text'],
+          '#eb_widget_main_submit' => TRUE,
+          '#attributes' => ['class' => ['is-entity-browser-submit']],
+          '#button_type' => 'primary',
+        ],
+      ];
+    }
 
     return $form;
   }
 
-
   /**
    * {@inheritdoc}
    */
   public function defaultConfiguration() {
-    return [
+    $defaultConfig = [
       'submit_text' => $this->t('Select entities'),
     ];
-  }
 
+    // If auto select is supported by Widget, append default configuration.
+    if ($this->getPluginDefinition()['autoSelect']) {
+      $defaultConfig['auto_select'] = FALSE;
+    }
+
+    return $defaultConfig;
+  }
 
   /**
    * {@inheritdoc}
@@ -197,6 +215,15 @@ abstract class WidgetBase extends PluginBase implements WidgetInterface, Contain
       '#default_value' => $this->configuration['submit_text'],
     ];
 
+    // Allow "auto_select" setting when autoSelect is supported by widget.
+    if ($this->getPluginDefinition()['autoSelect']) {
+      $form['auto_select'] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Automatically submit selection'),
+        '#default_value' => $this->configuration['auto_select'],
+      ];
+    }
+
     return $form;
   }
 
@@ -323,4 +350,11 @@ abstract class WidgetBase extends PluginBase implements WidgetInterface, Contain
       ));
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function requiresJsCommands() {
+    return $this->getPluginDefinition()['autoSelect'] && $this->getConfiguration()['settings']['auto_select'];
+  }
+
 }
diff --git a/src/WidgetInterface.php b/src/WidgetInterface.php
index 861033e..0a1140f 100644
--- a/src/WidgetInterface.php
+++ b/src/WidgetInterface.php
@@ -109,4 +109,13 @@ interface WidgetInterface extends PluginInspectionInterface, ConfigurablePluginI
    */
   public function submit(array &$element, array &$form, FormStateInterface $form_state);
 
+  /**
+   * Returns if widget requires JS commands support by selection display.
+   *
+   * @return bool
+   *   True is auto selection is enabled and add/remove of entities will be done
+   *   over javascript events on selection display.
+   */
+  public function requiresJsCommands();
+
 }
diff --git a/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml b/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml
new file mode 100644
index 0000000..4610a12
--- /dev/null
+++ b/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_grid.yml
@@ -0,0 +1,413 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_browser
+    - file
+    - user
+id: files_entity_browser_grid
+label: 'Files entity browser Grid'
+module: views
+description: ''
+tag: ''
+base_table: file_managed
+base_field: fid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: mini
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: ‹‹
+            next: ››
+      style:
+        type: grid
+        options:
+          grouping: {  }
+          columns: 2
+          automatic_width: true
+          alignment: horizontal
+          col_class_default: true
+          col_class_custom: ''
+          row_class_default: true
+          row_class_custom: ''
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: file_managed
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: file
+          plugin_id: entity_browser_select
+        filename:
+          id: filename
+          table: file_managed
+          field: filename
+          entity_type: file
+          entity_field: filename
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          link_to_file: true
+          plugin_id: file
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+        created:
+          id: created
+          table: file_managed
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Created
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: fallback
+          custom_date_format: ''
+          timezone: ''
+          entity_type: file
+          entity_field: created
+          plugin_id: date
+        filesize:
+          id: filesize
+          table: file_managed
+          field: filesize
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'File size'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          file_size_display: formatted
+          entity_type: file
+          entity_field: filesize
+          plugin_id: file_size
+        status:
+          id: status
+          table: file_managed
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: file
+          entity_field: status
+          plugin_id: file_status
+      filters:
+        filename:
+          id: filename
+          table: file_managed
+          field: filename
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: contains
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: filename_op
+            label: Filename
+            description: ''
+            use_operator: false
+            operator: filename_op
+            identifier: filename
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: file
+          entity_field: filename
+          plugin_id: string
+      sorts:
+        created:
+          id: created
+          table: file_managed
+          field: created
+          order: DESC
+          entity_type: file
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 2
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
diff --git a/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml b/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml
new file mode 100644
index 0000000..7a1586d
--- /dev/null
+++ b/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_html.yml
@@ -0,0 +1,411 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_browser
+    - file
+    - user
+id: files_entity_browser_html
+label: 'Files entity browser HTML'
+module: views
+description: ''
+tag: ''
+base_table: file_managed
+base_field: fid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: mini
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: ‹‹
+            next: ››
+      style:
+        type: html_list
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          type: ul
+          wrapper_class: item-list
+          class: ''
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: file_managed
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Entity browser bulk select form'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: file
+          plugin_id: entity_browser_select
+        filename:
+          id: filename
+          table: file_managed
+          field: filename
+          entity_type: file
+          entity_field: filename
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          link_to_file: true
+          plugin_id: file
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+        created:
+          id: created
+          table: file_managed
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Created
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: fallback
+          custom_date_format: ''
+          timezone: ''
+          entity_type: file
+          entity_field: created
+          plugin_id: date
+        filesize:
+          id: filesize
+          table: file_managed
+          field: filesize
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'File size'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          file_size_display: formatted
+          entity_type: file
+          entity_field: filesize
+          plugin_id: file_size
+        status:
+          id: status
+          table: file_managed
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: file
+          entity_field: status
+          plugin_id: file_status
+      filters:
+        filename:
+          id: filename
+          table: file_managed
+          field: filename
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: contains
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: filename_op
+            label: Filename
+            description: ''
+            use_operator: false
+            operator: filename_op
+            identifier: filename
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: file
+          entity_field: filename
+          plugin_id: string
+      sorts:
+        created:
+          id: created
+          table: file_managed
+          field: created
+          order: DESC
+          entity_type: file
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
diff --git a/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml b/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml
new file mode 100644
index 0000000..7792d65
--- /dev/null
+++ b/tests/modules/entity_browser_test/config/install/views.view.files_entity_browser_unformatted.yml
@@ -0,0 +1,408 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_browser
+    - file
+    - user
+id: files_entity_browser_unformatted
+label: 'Files entity browser Unformatted'
+module: views
+description: ''
+tag: ''
+base_table: file_managed
+base_field: fid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: mini
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          expose:
+            items_per_page: false
+            items_per_page_label: 'Items per page'
+            items_per_page_options: '5, 10, 25, 50'
+            items_per_page_options_all: false
+            items_per_page_options_all_label: '- All -'
+            offset: false
+            offset_label: Offset
+          tags:
+            previous: ‹‹
+            next: ››
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        entity_browser_select:
+          id: entity_browser_select
+          table: file_managed
+          field: entity_browser_select
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Entity browser bulk select form'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: file
+          plugin_id: entity_browser_select
+        filename:
+          id: filename
+          table: file_managed
+          field: filename
+          entity_type: file
+          entity_field: filename
+          label: ''
+          alter:
+            alter_text: false
+            make_link: false
+            absolute: false
+            trim: false
+            word_boundary: false
+            ellipsis: false
+            strip_tags: false
+            html: false
+          hide_empty: false
+          empty_zero: false
+          link_to_file: true
+          plugin_id: file
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exclude: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_alter_empty: true
+        created:
+          id: created
+          table: file_managed
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Created
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          date_format: fallback
+          custom_date_format: ''
+          timezone: ''
+          entity_type: file
+          entity_field: created
+          plugin_id: date
+        filesize:
+          id: filesize
+          table: file_managed
+          field: filesize
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'File size'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          file_size_display: formatted
+          entity_type: file
+          entity_field: filesize
+          plugin_id: file_size
+        status:
+          id: status
+          table: file_managed
+          field: status
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Status
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: null
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: file
+          entity_field: status
+          plugin_id: file_status
+      filters:
+        filename:
+          id: filename
+          table: file_managed
+          field: filename
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: contains
+          value: ''
+          group: 1
+          exposed: true
+          expose:
+            operator_id: filename_op
+            label: Filename
+            description: ''
+            use_operator: false
+            operator: filename_op
+            identifier: filename
+            required: false
+            remember: false
+            multiple: false
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          entity_type: file
+          entity_field: filename
+          plugin_id: string
+      sorts:
+        created:
+          id: created
+          table: file_managed
+          field: created
+          order: DESC
+          entity_type: file
+          entity_field: created
+          plugin_id: date
+          relationship: none
+          group_type: group
+          admin_label: ''
+          exposed: false
+          expose:
+            label: ''
+          granularity: second
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
+  entity_browser_1:
+    display_plugin: entity_browser
+    id: entity_browser_1
+    display_title: 'Entity browser'
+    position: 1
+    display_options:
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
diff --git a/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php b/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php
index 345609a..f7f62a5 100644
--- a/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php
+++ b/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/DummyWidget.php
@@ -11,7 +11,8 @@ use Drupal\entity_browser\WidgetBase;
  * @EntityBrowserWidget(
  *   id = "dummy",
  *   label = @Translation("Dummy widget"),
- *   description = @Translation("Dummy widget existing for testing purposes.")
+ *   description = @Translation("Dummy widget existing for testing purposes."),
+ *   autoSelect = FALSE
  * )
  */
 class DummyWidget extends WidgetBase {
diff --git a/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/MultipleSubmitTestWidget.php b/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/MultipleSubmitTestWidget.php
index 51a982e..79bebb3 100644
--- a/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/MultipleSubmitTestWidget.php
+++ b/tests/modules/entity_browser_test/src/Plugin/EntityBrowser/Widget/MultipleSubmitTestWidget.php
@@ -11,7 +11,8 @@ use Drupal\entity_browser\WidgetBase;
  * @EntityBrowserWidget(
  *   id = "multiple_submit_test_widget",
  *   label = @Translation("Multiple submit test widget"),
- *   description = @Translation("Test widget with multiple submit buttons only for testing purposes.")
+ *   description = @Translation("Test widget with multiple submit buttons only for testing purposes."),
+ *   autoSelect = FALSE
  * )
  */
 class MultipleSubmitTestWidget extends WidgetBase {
diff --git a/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php b/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php
index 3442f26..568a595 100644
--- a/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php
+++ b/tests/src/FunctionalJavascript/EntityBrowserJavascriptTestBase.php
@@ -2,14 +2,12 @@
 
 namespace Drupal\Tests\entity_browser\FunctionalJavascript;
 
-use Drupal\Component\Utility\SafeMarkup;
-use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\file\Entity\File;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-use Drupal\Tests\Component\Utility\SafeMarkupTest;
 
 /**
  * Base class for Entity browser Javascript functional tests.
@@ -108,11 +106,13 @@ abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
    *   The widget selector configuration.
    * @param array $selection_display_configuration
    *   The selection display configuration.
+   * @param array $widget_configurations
+   *   Widget configurations. Have be provided with widget UUIDs.
    *
    * @return \Drupal\entity_browser\EntityBrowserInterface
    *   Returns an Entity Browser.
    */
-  protected function getEntityBrowser($browser_name, $display_id, $widget_selector_id, $selection_display_id, $display_configuration = [], $widget_selector_configuration = [], $selection_display_configuration = []) {
+  protected function getEntityBrowser($browser_name, $display_id, $widget_selector_id, $selection_display_id, array $display_configuration = [], array $widget_selector_configuration = [], array $selection_display_configuration = [], array $widget_configurations = []) {
     /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
     $storage = $this->container->get('entity_type.manager')
       ->getStorage('entity_browser');
@@ -136,6 +136,15 @@ abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
       $browser->getSelectionDisplay()
         ->setConfiguration($selection_display_configuration);
     }
+
+    // Apply custom widget configurations.
+    if ($widget_configurations) {
+      foreach ($widget_configurations as $widget_uuid => $widget_config) {
+        $view_widget = $browser->getWidget($widget_uuid);
+        $view_widget->setConfiguration(NestedArray::mergeDeep($view_widget->getConfiguration(), $widget_config));
+      }
+    }
+
     $browser->save();
 
     // Clear caches after new browser is saved to remove old cached states.
@@ -191,6 +200,22 @@ abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
   }
 
   /**
+   * Click on element found by xpath selector.
+   *
+   * @param string $xpathSelector
+   *   Xpath selector for element that will be used to trigger click on it.
+   * @param bool $waitAfterAction
+   *   Flag to wait after click is executed.
+   */
+  protected function clickXpathSelector($xpathSelector, $waitAfterAction = TRUE) {
+    $this->getSession()->getPage()->find('xpath', $xpathSelector)->click();
+
+    if ($waitAfterAction) {
+      $this->waitForAjaxToFinish();
+    }
+  }
+
+  /**
    * Debugger method to save additional HTML output.
    *
    * The base class will only save browser output when accessing page using
@@ -210,5 +235,4 @@ abstract class EntityBrowserJavascriptTestBase extends JavascriptTestBase {
     }
   }
 
-
 }
diff --git a/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php b/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php
new file mode 100644
index 0000000..bfbd06a
--- /dev/null
+++ b/tests/src/FunctionalJavascript/MultiStepSelectionDisplayTest.php
@@ -0,0 +1,253 @@
+<?php
+
+namespace Drupal\Tests\entity_browser\FunctionalJavascript;
+
+use Drupal\Component\Utility\NestedArray;
+
+/**
+ * Test for multi_step_display selection display.
+ *
+ * @group entity_browser
+ *
+ * @package Drupal\Tests\entity_browser\FunctionalJavascript
+ */
+class MultiStepSelectionDisplayTest extends EntityBrowserJavascriptTestBase {
+
+  /**
+   * Open iframe entity browser and change scope to iframe.
+   */
+  protected function openEntityBrowser() {
+    $this->getSession()->getPage()->clickLink('Select entities');
+    $this->getSession()
+      ->switchToIFrame('entity_browser_iframe_test_entity_browser_file');
+    $this->waitForAjaxToFinish();
+  }
+
+  /**
+   * Close iframe entity browser and change scope to base page.
+   */
+  protected function closeEntityBrowser() {
+    $this->clickXpathSelector('//*[@data-drupal-selector="edit-use-selected"]');
+    $this->getSession()->switchToIFrame();
+    $this->waitForAjaxToFinish();
+  }
+
+  /**
+   * Click on entity in view to be selected.
+   *
+   * @param string $entityId
+   *   Entity ID that will be selected. Format: "file:1".
+   */
+  protected function clickViewEntity($entityId) {
+    $xpathViewRow = '//*[./*[contains(@class, "views-field-entity-browser-select") and .//input[@name="entity_browser_select[' . $entityId . ']"]]]';
+
+    $this->clickXpathSelector($xpathViewRow, FALSE);
+  }
+
+  /**
+   * Wait for Ajax Commands to finish.
+   *
+   * Since commands are executed in batches, it can occur that one command is
+   * still running and new one will be collected for next batch. To ensure all
+   * of commands are executed, we have to add additional 200ms wait, before next
+   * batch is triggered.
+   *
+   * It's related to: Drupal.entityBrowserCommandQueue.executeCommands
+   */
+  protected function waitSelectionDisplayAjaxCommands() {
+    $this->waitForAjaxToFinish();
+    $this->getSession()->wait(200);
+    $this->waitForAjaxToFinish();
+  }
+
+  /**
+   * Change selection mode for article reference field form display widget.
+   *
+   * @param array $configuration
+   *   Configuration that will be used for field form display.
+   */
+  protected function changeFieldFormDisplayConfig(array $configuration) {
+    /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
+    $form_display = $this->container->get('entity_type.manager')
+      ->getStorage('entity_form_display')
+      ->load('node.article.default');
+
+    $form_display->setComponent(
+      'field_reference',
+      NestedArray::mergeDeep($form_display->getComponent('field_reference'), $configuration)
+    )->save();
+  }
+
+  /**
+   * Check that selection state in entity browser Inline Entity Form.
+   */
+  public function testAjaxCommands() {
+
+    $this->createFile('test_file1');
+    $this->createFile('test_file2');
+    $this->createFile('test_file3');
+
+    // Testing Action buttons (adding and removing) with usage of HTML View.
+    $widget_configurations = [
+      // View widget configuration.
+      '774798f1-5ec5-4b63-84bd-124cd51ec07d' => [
+        'settings' => [
+          'view' => 'files_entity_browser_html',
+          'auto_select' => TRUE,
+        ],
+      ],
+    ];
+    $this->getEntityBrowser('test_entity_browser_file', 'iframe', 'tabs', 'multi_step_display', [], [], [], $widget_configurations);
+    $this->drupalGet('node/add/article');
+    $this->openEntityBrowser();
+
+    // Check that action buttons are not there.
+    $this->assertSession()
+      ->elementNotExists('xpath', '//*[@data-drupal-selector="edit-use-selected"]');
+    $this->assertSession()
+      ->elementNotExists('xpath', '//*[@data-drupal-selector="edit-show-selection"]');
+
+    $this->clickViewEntity('file:1');
+    $this->waitSelectionDisplayAjaxCommands();
+
+    // Check that action buttons are there.
+    $this->assertSession()
+      ->elementExists('xpath', '//*[@data-drupal-selector="edit-use-selected"]');
+    $this->assertSession()
+      ->elementExists('xpath', '//*[@data-drupal-selector="edit-show-selection"]');
+
+    // Click on first entity Remove button.
+    $this->clickXpathSelector('//input[@data-row-id="0"]');
+    $this->waitSelectionDisplayAjaxCommands();
+
+    // Check that action buttons are not there.
+    $this->assertSession()
+      ->elementNotExists('xpath', '//*[@data-drupal-selector="edit-use-selected"]');
+    $this->assertSession()
+      ->elementNotExists('xpath', '//*[@data-drupal-selector="edit-show-selection"]');
+
+    $this->clickViewEntity('file:1');
+    $this->waitSelectionDisplayAjaxCommands();
+    $this->closeEntityBrowser();
+
+    // Testing quick adding and removing of entities with usage of Table
+    // (default) view.
+    $widget_configurations = [
+      // View widget configuration.
+      '774798f1-5ec5-4b63-84bd-124cd51ec07d' => [
+        'settings' => [
+          'view' => 'files_entity_browser',
+          'auto_select' => TRUE,
+        ],
+      ],
+    ];
+    $this->getEntityBrowser('test_entity_browser_file', 'iframe', 'tabs', 'multi_step_display', [], [], [], $widget_configurations);
+    $this->drupalGet('node/add/article');
+    $this->openEntityBrowser();
+
+    // Quickly add 5 entities.
+    $entitiesToAdd = ['file:1', 'file:2', 'file:3', 'file:1', 'file:2'];
+    foreach ($entitiesToAdd as $entityId) {
+      $this->clickViewEntity($entityId);
+    }
+    $this->waitSelectionDisplayAjaxCommands();
+
+    // Check that there are 5 entities in selection display list.
+    $this->assertSession()
+      ->elementsCount('xpath', '//div[contains(@class, "entities-list")]/*', 5);
+
+    // Quickly remove all 5 entities.
+    foreach (array_keys($entitiesToAdd) as $entityIndex) {
+      $this->clickXpathSelector('//input[@data-row-id="' . $entityIndex . '"]');
+    }
+    $this->waitSelectionDisplayAjaxCommands();
+
+    // Check that action buttons are not there.
+    $this->assertSession()
+      ->elementNotExists('xpath', '//*[@data-drupal-selector="edit-use-selected"]');
+    $this->assertSession()
+      ->elementNotExists('xpath', '//*[@data-drupal-selector="edit-show-selection"]');
+
+    $this->clickViewEntity('file:1');
+    $this->waitSelectionDisplayAjaxCommands();
+    $this->closeEntityBrowser();
+
+    // Testing adding with preselection with usage of Grid view.
+    $widget_configurations = [
+      // View widget configuration.
+      '774798f1-5ec5-4b63-84bd-124cd51ec07d' => [
+        'settings' => [
+          'view' => 'files_entity_browser_grid',
+          'auto_select' => TRUE,
+        ],
+      ],
+    ];
+    $this->getEntityBrowser('test_entity_browser_file', 'iframe', 'tabs', 'multi_step_display', [], [], [], $widget_configurations);
+
+    // Change selection mode to 'Edit', to test adding/removing inside EB.
+    $this->changeFieldFormDisplayConfig([
+      'settings' => [
+        'selection_mode' => 'selection_edit',
+      ],
+    ]);
+
+    $this->drupalGet('node/add/article');
+    $this->openEntityBrowser();
+
+    $this->clickViewEntity('file:1');
+    $this->waitSelectionDisplayAjaxCommands();
+    $this->closeEntityBrowser();
+
+    $this->openEntityBrowser();
+
+    $this->clickViewEntity('file:2');
+    $this->waitSelectionDisplayAjaxCommands();
+    $this->closeEntityBrowser();
+
+    $this->assertSession()
+      ->elementsCount('xpath', '//div[contains(@class, "entities-list")]/*', 2);
+
+    // Testing removing with preselection with usage of Unformatted view.
+    $widget_configurations = [
+      // View widget configuration.
+      '774798f1-5ec5-4b63-84bd-124cd51ec07d' => [
+        'settings' => [
+          'view' => 'files_entity_browser_unformatted',
+          'auto_select' => TRUE,
+        ],
+      ],
+    ];
+    $this->getEntityBrowser('test_entity_browser_file', 'iframe', 'tabs', 'multi_step_display', [], [], [], $widget_configurations);
+
+    $this->drupalGet('node/add/article');
+    $this->openEntityBrowser();
+
+    // Select 3 entities.
+    $entitiesToAdd = ['file:1', 'file:2', 'file:3'];
+    foreach ($entitiesToAdd as $entityId) {
+      $this->clickViewEntity($entityId);
+
+      // For some reason PhantomJS crashes here on quick clicking. That's why
+      // waiting is added. Selenium works fine.
+      $this->waitSelectionDisplayAjaxCommands();
+    }
+    $this->closeEntityBrowser();
+
+    // Check that there are 3 entities in selection list after closing of EB.
+    $this->assertSession()
+      ->elementsCount('xpath', '//div[contains(@class, "entities-list")]/*', 3);
+
+    $this->openEntityBrowser();
+
+    // Click on first entity Remove button.
+    $this->clickXpathSelector('//input[@data-row-id="0"]');
+    $this->waitSelectionDisplayAjaxCommands();
+
+    $this->closeEntityBrowser();
+
+    // Check that there are 2 entities in selection list after closing of EB.
+    $this->assertSession()
+      ->elementsCount('xpath', '//div[contains(@class, "entities-list")]/*', 2);
+  }
+
+}
diff --git a/tests/src/Kernel/Extension/EntityBrowserTest.php b/tests/src/Kernel/Extension/EntityBrowserTest.php
index 0c33bf6..9a49df0 100644
--- a/tests/src/Kernel/Extension/EntityBrowserTest.php
+++ b/tests/src/Kernel/Extension/EntityBrowserTest.php
@@ -178,6 +178,7 @@ class EntityBrowserTest extends KernelTestBase {
             'view' => 'test_view',
             'view_display' => 'test_display',
             'submit_text' => 'Select entities',
+            'auto_select' => FALSE,
           ],
         ],
       ],
