x^diff --git a/config/schema/entity_browser.schema.yml b/config/schema/entity_browser.schema.yml
index 3677c16..82dcac2 100644
--- a/config/schema/entity_browser.schema.yml
+++ b/config/schema/entity_browser.schema.yml
@@ -91,6 +91,9 @@ entity_browser.browser.widget.upload:
     submit_text:
       type: string
       label: 'Submit button text'
+    auto_select:
+      type: boolean
+      label: 'Automatically submit selection'
     upload_location:
       type: string
       label: 'Upload location'
@@ -102,6 +105,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..9a62138
--- /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 commandName
+   *   Command name, that will be executed.
+   * @param 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));
\ No newline at end of file
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..45c68ec 100644
--- a/js/entity_browser.view.js
+++ b/js/entity_browser.view.js
@@ -47,6 +47,29 @@
             }
           });
         });
+
+        // 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) {
+          views_instance.$view.find('tr')
+            .once('register-row-click')
+            .click(function (event) {
+              event.preventDefault();
+
+              var $row = $(this);
+              var $input = $row.find('input');
+
+              $row.parents('form')
+                .find('.entities-list')
+                .trigger('add-entities', [[$input.val()]]);
+            });
+
+          // Hide column with checkboxes.
+          views_instance.$view.find('.views-field-entity-browser-select')
+            .hide();
+        }
       }
     }
   };
diff --git a/modules/entity_form/config/schema/entity_browser_entity_form.schema.yml b/modules/entity_form/config/schema/entity_browser_entity_form.schema.yml
index 16928a1..0985f59 100644
--- a/modules/entity_form/config/schema/entity_browser_entity_form.schema.yml
+++ b/modules/entity_form/config/schema/entity_browser_entity_form.schema.yml
@@ -13,6 +13,9 @@ entity_browser.browser.widget.entity_form:
     submit_text:
       type: string
       label: 'Submit button text'
+    auto_select:
+      type: boolean
+      label: 'Automatically submit selection'
     entity_type:
       type: string
       label: 'Entity type ID'
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 @@
  * @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 a12307c..8d0a73e 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..76338b8
--- /dev/null
+++ b/modules/example/config/install/entity_browser.browser.test_files_ajax.yml
@@ -0,0 +1,45 @@
+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'
+      auto_select: false
+    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 ac290da..dad7127 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;
@@ -75,7 +76,7 @@ public function setEntityBrowser(EntityBrowserInterface $entity_browser) {
   /**
    * Initializes form state.
    *
-   * @param \Drupal\Core\Form\FormStateInterface
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   Form state object.
    */
   protected function init(FormStateInterface $form_state) {
@@ -109,6 +110,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       $this->init($form_state);
     }

+    $this->isFunctionalForm($form_state);
+
     $form['#attributes']['class'][] = 'entity-browser-form';
     $form['#browser_parts'] = [
       'widget_selector' => 'widget_selector',
@@ -140,6 +143,25 @@ public function buildForm(array $form, FormStateInterface $form_state) {
   }

   /**
+   * Check if entity browser with selected configuration combination can work.
+   *
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   Form status.
+   */
+  protected function isFunctionalForm(FormStateInterface $form_state) {
+    /** @var \Drupal\entity_browser\WidgetInterface $widget */
+    $widget = $this->entity_browser->getWidgets()
+      ->get($this->getCurrentWidget($form_state));
+
+    /** @var \Drupal\entity_browser\SelectionDisplayInterface $selectionDisplay */
+    $selectionDisplay = $this->entity_browser->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..39abd3b 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 @@
  *   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 @@ public function defaultConfiguration() {
    * {@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 @@ public function getForm(array &$original_form, FormStateInterface $form_state) {
           '#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 @@ public function getForm(array &$original_form, FormStateInterface $form_state) {
         ],
       ];
     }
+
+    // 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,153 @@ public function getForm(array &$original_form, FormStateInterface $form_state) {
   }

   /**
+   * 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'] . '"]', trim($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', trim($renderer->render($form['selection_display']['show_selection'])))
+          );
+
+          $ajax->addCommand(
+            new AfterCommand('.entities-list', trim($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;
+  }
+
+  /**
    * 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 7770166..3b9e468 100644
--- a/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php
+++ b/src/Plugin/EntityBrowser/SelectionDisplay/NoDisplay.php
@@ -12,7 +12,8 @@
  *   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 @@
  *   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 e65dc86..3e0b13a 100644
--- a/src/Plugin/EntityBrowser/Widget/Upload.php
+++ b/src/Plugin/EntityBrowser/Widget/Upload.php
@@ -19,7 +19,8 @@
  * @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 {
@@ -166,6 +167,14 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#default_value' => $this->configuration['submit_text'],
     ];

+    // Allow "auto_select" setting when autoSelect is supported by widget.
+    $form['auto_select'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Automatically submit selection'),
+      '#default_value' => $this->configuration['auto_select'],
+      '#disabled' => !$this->getPluginDefinition()['autoSelect'],
+    ];
+
     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 @@
  *   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 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
   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 @@ public function checkPreselectionSupport() {
   }

   /**
+   * {@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 @@ public function submit(array &$form, FormStateInterface $form_state);
    */
   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 54121ae..0d8aac7 100644
--- a/src/Tests/ConfigUITest.php
+++ b/src/Tests/ConfigUITest.php
@@ -200,13 +200,31 @@ public function testConfigUI() {
     $this->assertEqual('upload', $widget->id(), 'Entity browser widget was correctly saved.');
     $this->assertEqual($first_uuid, $widget->uuid(), 'Entity browser widget uuid was correctly saved.');
     $configuration = $widget->getConfiguration()['settings'];
-    $this->assertEqual(['upload_location' => 'public://', 'submit_text' => 'Select files'], $configuration, 'Entity browser widget configuration was correctly saved.');
+    $this->assertEqual(
+      [
+        'upload_location' => 'public://',
+        'submit_text' => 'Select files',
+        'auto_select' => FALSE,
+      ],
+      $configuration,
+      'Entity browser widget configuration was correctly saved.'
+    );
     $this->assertEqual(1, $widget->getWeight(), 'Entity browser widget weight was correctly saved.');
     $widget = $widgets->get($second_uuid);
     $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',
+        'auto_select' => FALSE,
+      ],
+      $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 a7c8fb7..d78e532 100644
--- a/src/WidgetBase.php
+++ b/src/WidgetBase.php
@@ -109,6 +109,8 @@ public static function create(ContainerInterface $container, array $configuratio
    * {@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,33 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a
       }
     }

-    $form['actions'] = [
-      '#type' => 'actions',
-      'submit' => [
-        '#type' => 'submit',
-        '#value' => $this->configuration['submit_text'],
-        '#eb_widget_main_submit' => TRUE,
-        '#attributes' => ['class' => ['is-entity-browser-submit']],
-      ],
-    ];
+    // In case of auto submitting, widget will handle adding entities in JS.
+    $form['#attached']['drupalSettings']['entity_browser_widget']['auto_select'] = $this->configuration['auto_select'];
+    if (!$this->configuration['auto_select']) {
+      $form['actions'] = [
+        '#type' => 'actions',
+        'submit' => [
+          '#type' => 'submit',
+          '#value' => $this->configuration['submit_text'],
+          '#eb_widget_main_submit' => TRUE,
+          '#attributes' => ['class' => ['is-entity-browser-submit']],
+        ],
+      ];
+    }

     return $form;
   }

-
   /**
    * {@inheritdoc}
    */
   public function defaultConfiguration() {
     return [
       'submit_text' => $this->t('Select entities'),
+      'auto_select' => FALSE,
     ];
   }

-
   /**
    * {@inheritdoc}
    */
@@ -196,6 +201,14 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#default_value' => $this->configuration['submit_text'],
     ];

+    // Allow "auto_select" setting when autoSelect is supported by widget.
+    $form['auto_select'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Automatically submit selection'),
+      '#default_value' => $this->configuration['auto_select'],
+      '#disabled' => !$this->getPluginDefinition()['autoSelect'],
+    ];
+
     return $form;
   }

@@ -322,4 +335,11 @@ protected function selectEntities(array $entities, FormStateInterface $form_stat
       ));
   }

+  /**
+   * {@inheritdoc}
+   */
+  public function requiresJsCommands() {
+    return $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 @@ public function validate(array &$form, FormStateInterface $form_state);
    */
   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/schema/entity_browser_test.schema.yml b/tests/modules/entity_browser_test/config/schema/entity_browser_test.schema.yml
index 3eb0256..f5370f9 100644
--- a/tests/modules/entity_browser_test/config/schema/entity_browser_test.schema.yml
+++ b/tests/modules/entity_browser_test/config/schema/entity_browser_test.schema.yml
@@ -5,6 +5,9 @@ entity_browser.browser.widget.dummy:
     submit_text:
       type: string
       label: 'Submit button text'
+    auto_select:
+      type: boolean
+      label: 'Automatically submit selection'
     text:
       type: string
       label: 'Text'
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 @@
  * @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/src/Kernel/Extension/EntityBrowserTest.php b/tests/src/Kernel/Extension/EntityBrowserTest.php
index f49ef02..5829382 100644
--- a/tests/src/Kernel/Extension/EntityBrowserTest.php
+++ b/tests/src/Kernel/Extension/EntityBrowserTest.php
@@ -166,6 +166,7 @@ protected function createTests() {
             'view' => 'test_view',
             'view_display' => 'test_display',
             'submit_text' => 'Select entities',
+            'auto_select' => FALSE,
           ],
         ],
       ],
