diff --git a/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php b/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php index a25e90a..5bb40d1 100644 --- a/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php +++ b/src/Plugin/Field/FieldWidget/EntityReferenceBrowserWidget.php @@ -481,7 +481,6 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor * The render array for the current selection. */ protected function displayCurrentSelection($details_id, $field_parents, $entities) { - $field_widget_display = $this->fieldDisplayManager->createInstance( $this->getSetting('field_widget_display'), $this->getSetting('field_widget_display_settings') + ['entity_type' => $this->fieldDefinition->getFieldStorageDefinition()->getSetting('target_type')] @@ -495,6 +494,7 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor return [ '#theme_wrappers' => ['container'], '#attributes' => ['class' => $classes], + '#prefix' => '

' . $this->getCardinalityMessage($entities) . '

', 'items' => array_map( function (ContentEntityInterface $entity, $row_id) use ($field_widget_display, $details_id, $field_parents) { $display = $field_widget_display->view($entity); @@ -559,6 +559,42 @@ class EntityReferenceBrowserWidget extends WidgetBase implements ContainerFactor } /** + * Generates a message informing the user how many more items they can choose. + * + * @param array|int $selected + * The current selections, or how many items are selected. + * + * @return string + * A message informing the user who many more items they can select. + */ + protected function getCardinalityMessage($selected) { + $message = NULL; + + $storage = $this->fieldDefinition->getFieldStorageDefinition(); + $cardinality = $storage->getCardinality(); + $target_type = $storage->getSetting('target_type'); + $target_type = $this->entityTypeManager->getDefinition($target_type); + + if (is_array($selected)) { + $selected = count($selected); + } + + if ($cardinality === 1 && $selected === 0) { + $message = t('You can select one @entity_type.', [ + '@entity_type' => $target_type->getSingularLabel(), + ]); + } + elseif ($cardinality >= $selected) { + $message = t('You can select up to @maximum @entity_type (@remaining left).', [ + '@maximum' => $cardinality, + '@entity_type' => $target_type->getPluralLabel(), + '@remaining' => $cardinality - $selected, + ]); + } + return (string) $message; + } + + /** * Gets data that should persist across Entity Browser renders. * * @return array diff --git a/src/Plugin/Field/FieldWidget/FileBrowserWidget.php b/src/Plugin/Field/FieldWidget/FileBrowserWidget.php index 4d02753..0debe56 100644 --- a/src/Plugin/Field/FieldWidget/FileBrowserWidget.php +++ b/src/Plugin/Field/FieldWidget/FileBrowserWidget.php @@ -213,6 +213,7 @@ class FileBrowserWidget extends EntityReferenceBrowserWidget { $current = [ '#type' => 'table', '#empty' => $this->t('No files yet'), + '#prefix' => '

' . $this->getCardinalityMessage($entities) . '

', '#attributes' => ['class' => ['entities-list']], '#tabledrag' => [ [ diff --git a/tests/src/FunctionalJavascript/EntityBrowserTest.php b/tests/src/FunctionalJavascript/EntityBrowserTest.php index e8add2c..ce99e44 100644 --- a/tests/src/FunctionalJavascript/EntityBrowserTest.php +++ b/tests/src/FunctionalJavascript/EntityBrowserTest.php @@ -13,7 +13,6 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase { * Tests single widget selector. */ public function testSingleWidgetSelector() { - // Sets the single widget selector. /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */ $browser = $this->container->get('entity_type.manager') @@ -51,10 +50,75 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase { } /** + * Tests the field widget with a single-cardinality field. + */ + public function testSingleCardinalityField() { + $this->container->get('entity_type.manager') + ->getStorage('field_storage_config') + ->load('node.field_reference') + ->setCardinality(1) + ->save(); + + // Create a file. + $image = $this->createFile('llama'); + + $this->drupalGet('node/add/article'); + + $this->assertSession()->linkExists('Select entities'); + $this->assertSession()->pageTextContains('You can select one file.'); + $this->getSession()->getPage()->clickLink('Select entities'); + + $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file'); + + $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $image->id() . ']'); + $this->getSession()->getPage()->pressButton('Select entities'); + + // Switch back to the main page. + $this->getSession()->switchToIFrame(); + $this->waitForAjaxToFinish(); + // A selection has been made, so the message is no longer necessary. + $this->assertSession()->pageTextNotContains('You can select one file.'); + } + + /** + * Tests the field widget with a multi-cardinality field. + */ + public function testMultiCardinalityField() { + $this->container->get('entity_type.manager') + ->getStorage('field_storage_config') + ->load('node.field_reference') + ->setCardinality(3) + ->save(); + + // Create a few files to choose. + $images = []; + array_push($images, $this->createFile('llama')); + array_push($images, $this->createFile('sloth')); + array_push($images, $this->createFile('puppy')); + + $this->drupalGet('node/add/article'); + + $this->assertSession()->linkExists('Select entities'); + $this->assertSession()->pageTextContains('You can select up to 3 file entities (3 left).'); + $this->getSession()->getPage()->clickLink('Select entities'); + + $this->getSession()->switchToIFrame('entity_browser_iframe_test_entity_browser_file'); + + $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $images[0]->id() . ']'); + $this->getSession()->getPage()->checkField('entity_browser_select[file:' . $images[1]->id() . ']'); + $this->getSession()->getPage()->pressButton('Select entities'); + + // Switch back to the main page. + $this->getSession()->switchToIFrame(); + $this->waitForAjaxToFinish(); + // Selections have been made, so the message should be different. + $this->assertSession()->pageTextContains('You can select up to 3 file entities (1 left).'); + } + + /** * Tests tabs widget selector. */ public function testTabsWidgetSelector() { - // Sets the tabs widget selector. /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */ $browser = $this->container->get('entity_type.manager') @@ -108,7 +172,6 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase { * Tests dropdown widget selector. */ public function testDropdownWidgetSelector() { - // Sets the dropdown widget selector. /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */ $browser = $this->container->get('entity_type.manager') @@ -154,7 +217,6 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase { * Tests wievs selection display. */ public function testViewsSelectionDisplayWidget() { - // Sets the dropdown widget selector. /** @var \Drupal\entity_browser\EntityBrowserInterface $browser */ $browser = $this->container->get('entity_type.manager') @@ -164,7 +226,6 @@ class EntityBrowserTest extends EntityBrowserJavascriptTestBase { $browser->save(); $this->assertEquals($browser->getSelectionDisplay()->getPluginId(), 'view', 'Selection display is set to view.'); - } /**