Simplify adding Entity Browser form element to custom form

Created on 12 October 2016, over 7 years ago
Updated 20 February 2024, 4 months ago

Problem/Motivation

I'm trying to replace the link field on the core menu with an entity browser. But it's proving difficult to get good results. I have it so far as to display the "details" container and the "add entities" button. It opens a modal, displays the view, etc. But once I select entities from the view and it returns to the form it's not refreshing the form. I see the throbber image, but the form doesn't appear to be updated.

Upon looking at the page I can see the the entity id has been added, but it's been added to a generated hidden field instead of the target_id field I had created.

I modeled the render array after a node edit form entity browser widget.

Does anyone know how to get this to work?

Attached is my extremely long field definition. I'm pretty sure it's related to the naming on my divs, or including extra keys that don't need to be there. This is inside of a form_alter.

  $form['content_link'] = [
    '#type' => 'container',
    '#parents' => ['content_link_wrapper'],
    '#weight' => -3,
    'widget' => [
      '#title' => t('Content Link'),
      '#description' => t('The content to be linked in the menu.'),
      '#field_name' => 'content_link',
      '#field_parents' => [],
      '#required' => TRUE,
      '#parents' => ['content_link'],
      '#tree' => TRUE,
      '#id' => 'edit-content-link',
      '#type' => 'details',
      '#open' => TRUE,
      'target_id' => [
        '#type' => 'hidden',
        '#id' => 'edit-content-link-target-id',
        '#attributes' => [
          'id' => 'edit-content-link-target-id',
        ],
        '#default_value' => "",
        '#ajax' => [
          'callback' => [
            'Drupal\entity_browser\Plugin\Field\FieldWidget\EntityReferenceBrowserWidget',
            'updateWidgetCallback',
          ],
          'wrapper' => 'edit-content-link',
          'event' => 'entity_browser_value_updated',
        ],
      ],
      'entity_browser' => [
        '#type' => 'entity_browser',
        '#entity_browser' => 'content_hub_page_browser',
        '#cardinality' => 1,
        '#selection_mode' => 'selection_append',
        '#default_value' => [],
        '#entity_browser_validators' => [
          'entity_type' => [
            'type' => 'node',
          ],
        ],
        '#custom_hidden_id' => 'edit-content-link-target-id',
        '#process' => [
          [
            '\Drupal\entity_browser\Element\EntityBrowserElement',
            'processEntityBrowser',
          ],
          [
            'Drupal\entity_browser\Plugin\Field\FieldWidget\EntityReferenceBrowserWidget',
            'processEntityBrowser',
          ],
        ]
      ],
      'current' => [
        '#theme_wrappers' => ['container'],
        '#attributes' => [
          'class' => 'entities-list',
        ],
        'items' => [],
      ],
      '#after_build' => [
        [
          'Drupal\entity_browser\Plugin\Field\FieldWidget\EntityReferenceBrowserWidget',
          'afterBuild',
        ],
      ],
      '#attached' => [
        'library' => [
          'entity_browser/entity_reference',
        ],
      ],
    ],
  ];
✨ Feature request
Status

Needs work

Version

2.0

Component

Miscellaneous

Created by

πŸ‡ΊπŸ‡ΈUnited States merauluka

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡«πŸ‡·France arnaud-brugnon

    #21 works for me in custom form only if we had #tree = TRUE

      /**
       * {@inheritDoc}
       */
      public function buildForm(array $form, FormStateInterface $form_state) {
        $form['background_image'] = $this->getEntityBrowserForm(
          'paragraphs_library_items', // Entity Browser config entity ID
          $this->configuration['background_image'], // Default value as a string
          1, // Cardinality
          'preview' // The view mode to use when displaying the entity in the selected entities table
        );
        
        // Convert the wrapping container to a details element.
        $form['background_image']['#type'] = 'details';
        $form['background_image']['#title'] = $this->t('Background image');
        $form['background_image']['#open'] = TRUE;
        $form['background_image']['#tree'] = TRUE;
        return $form;
      }
    
  • πŸ‡¨πŸ‡­Switzerland florianmuellerCH Aarau, Switzerland

    Thank you all for your work! #21 and the info in #22 helped me a lot!

    I added a JS behavior to make the selected elements sortable. To do that I had to add my library and a class in the base element:

        $element = [
          '#type' => 'details', // I added this directly here
          '#open' => $default_open, // I added this as a parameter
          '#title' => $title, // I added this as a parameter
          '#attributes' => [
            'id' => Html::getUniqueId('entity-browser-' . $entity_browser_id . '-wrapper'),
            'class' => [
              'entity-browser-form-trait-element', // NEW CLASS for JS behavior
            ]
          ],
          '#attached' => [
            'library' => [
              'my_module/entity-browser-trait' // ATTACH new library
            ]
          ]
        ];
    

    Be sure to add the dependency to core/sortable in your libraries.yml.

    (function ($) {
    
      Drupal.behaviors.entityBrowserTraitSortable = {
        attach: function (context, settings) {
          $(once('sortable-entity-browser-images', '.entity-browser-form-trait-element table.responsive-enabled tbody')).each(function() {
            let $tbody = $(this);
            let $parent = $tbody.closest('.entity-browser-form-trait-element');
            $tbody.find('>tr').css('cursor', 'move'); // This is a convenience thing and could be moved to CSS
            Sortable.create($tbody[0], {
              onEnd: function (e) {
                let $to = $(e.to);
                let list = [];
                $to.children('tr').each(function() {
                  list.push($(this).attr('data-entity-id'));
                });
                $parent.find('input[type="hidden"].eb-target').val(list.join(' '));
              }
            });
    
          })
        },
      };
    
    })(jQuery);
    
    
  • πŸ‡²πŸ‡½Mexico gnuget Puebla

    #21 worked for me too.

    Thanks!!!

  • I've been using the code in #21 for a while on my site and it has worked great! I had a custom ckeditor plugin that opened up a modal that contained a few form fields, one of which needed to open our custom entity browser. However, I've been attempting to upgrade to ckeditor5, and I can not get this functionality to work any longer.

    Clicking the button on the ckeditor5 toolbar opens up my modal successfully, and my other fields work...but I can't get the custom entity browser field to work correctly. Once I make a selection, I still see a 'No items selected yet' message. I would expect the image that I selected to appear there. Even if I hardcode media:123 for example as the default value, I still see the 'no items selected yet' message.

    Just wondering if anyone has seen a similar issue? I really don't know what could be causing this to happen.

Production build 0.69.0 2024