From 73743d25ef657052e96d4034c6356068d05d2076 Mon Sep 17 00:00:00 2001 From: Nenad Nesic Date: Wed, 20 Jan 2016 15:56:00 +0100 Subject: [PATCH] Issue #2605578 by CTaPByK, slashrsm: Create selection display plugin that will support multi-step flow. --- entity_browser.libraries.yml | 7 + js/entity_browser.multi_step_display.js | 39 ++++++ .../SelectionDisplay/MultiStepDisplay.php | 126 ++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 js/entity_browser.multi_step_display.js create mode 100644 src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php diff --git a/entity_browser.libraries.yml b/entity_browser.libraries.yml index e13cbf9..aaf4a6f 100644 --- a/entity_browser.libraries.yml +++ b/entity_browser.libraries.yml @@ -61,3 +61,10 @@ view: js: js/entity_browser.view.js: {} dependencies: + +multi_step_display: + version: VERSION + js: + js/entity_browser.multi_step_display.js: {} + dependencies: + - core/jquery.ui.sortable diff --git a/js/entity_browser.multi_step_display.js b/js/entity_browser.multi_step_display.js new file mode 100644 index 0000000..d307aa5 --- /dev/null +++ b/js/entity_browser.multi_step_display.js @@ -0,0 +1,39 @@ +/** + * @file entity_browser.multi_step_display.js + * + */ +(function ($, Drupal, drupalSettings) { + + "use strict"; + + /** + * Registers behaviours related to selected entities. + */ + Drupal.behaviors.entityBrowserMultiStepDisplay = { + attach: function (context) { + $(context).find('.entity-browser-form').each(function () { + $(this).find('.selected-entities-list').sortable({ + stop: Drupal.entityBrowserMultiStepDisplay.entitiesReordered + }); + }); + } + }; + + Drupal.entityBrowserMultiStepDisplay = {}; + + /** + * Reacts on sorting of the entities. + * + * @param event + * Event object. + * @param ui + * Object with detailed information about the sort event. + */ + Drupal.entityBrowserMultiStepDisplay.entitiesReordered = function(event, ui) { + var items = $(this).find('.selected-item-container'); + for (var i = 0; i < items.length; i++) { + $(items[i]).find('.weight').val(i); + } + }; + +}(jQuery, Drupal, drupalSettings)); diff --git a/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php b/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php new file mode 100644 index 0000000..f42918f --- /dev/null +++ b/src/Plugin/EntityBrowser/SelectionDisplay/MultiStepDisplay.php @@ -0,0 +1,126 @@ +get(['entity_browser', 'selected_entities']); + + $form = []; + $form['#attached']['library'][] = 'entity_browser/multi_step_display'; + $form['selected'] = [ + '#theme_wrappers' => ['container'], + '#attributes' => ['class' => ['selected-entities-list']], + '#tree' => TRUE + ]; + foreach ($selected_entities as $id => $entity) { + $form['selected']['items_'. $entity->id()] = [ + '#theme_wrappers' => ['container'], + '#attributes' => [ + 'class' => ['selected-item-container'], + 'data-entity-id' => $entity->id() + ], + 'display' => ['#markup' => $entity->label()], + 'remove_button' => [ + '#type' => 'submit', + '#value' => $this->t('Remove'), + '#submit' => [[get_class($this), 'removeItemSubmit']], + '#name' => 'remove_' . $entity->id(), + '#attributes' => [ + 'data-row-id' => $id, + 'data-remove-entity' => 'items_' . $entity->id(), + ] + ], + 'weight' => [ + '#type' => 'hidden', + '#default_value' => $id, + '#attributes' => ['class' => ['weight']] + ] + ]; + } + $form['use_selected'] = array( + '#type' => 'submit', + '#value' => t('Use selected'), + '#name' => 'use_selected', + ); + + return $form; + } + + /** + * Submit callback for remove buttons. + * + * @param array $form + * @param \Drupal\Core\Form\FormStateInterface $form_state + */ + public static function removeItemSubmit(array &$form, FormStateInterface $form_state) { + $triggering_element = $form_state->getTriggeringElement(); + + // Remove weight of entity being removed. + $form_state->unsetValue(['selected', $triggering_element['#attributes']['data-remove-entity']]); + + // Remove entity itself. + $selected_entities = &$form_state->get(['entity_browser', 'selected_entities']); + unset($selected_entities[$triggering_element['#attributes']['data-row-id']]); + + static::saveNewOrder($form_state); + $form_state->setRebuild(); + } + + /** + * {@inheritdoc} + */ + public function submit(array &$form, FormStateInterface $form_state) { + $this->saveNewOrder($form_state); + if ($form_state->getTriggeringElement()['#name'] == 'use_selected') { + $this->selectionDone($form_state); + } + } + + /** + * Saves new ordering of entities based on weight. + * + * @param FormStateInterface $form_state + * Form state. + */ + public static function saveNewOrder(FormStateInterface $form_state) { + $selected = $form_state->getValue('selected'); + if (!empty($selected)) { + $weights = array_column($selected, 'weight'); + $selected_entities = $form_state->get(['entity_browser', 'selected_entities']); + + // If we added new entities to the selection at this step we won't have + // weights for them so we have to fake them. + if (sizeof($weights) < sizeof($selected_entities)) { + for ($new_weigth = (max($weights) + 1); $new_weigth < sizeof($selected_entities); $new_weigth++) { + $weights[] = $new_weigth; + } + } + + $ordered = array_combine($weights, $selected_entities); + ksort($ordered); + $form_state->set(['entity_browser', 'selected_entities'], $ordered); + } + } + +}