By Simon Song


2019-05-15 18:26:53 8 Comments

I have a drupal 8 site that uses the paragraphs module. In one of the paragraph is a field that contains an autocomplete field. It is already set up to reference a small list of Content Types. For example, "News, Events, Product, Image" are four referenced for the autocomplete.

On another paragraph, it includes this autocomplete but also has a field called "Select a Content Type", it lists out ALL the content types. This is used on the content type. When someone adds a new content they are presented with a list of all the content types as a checkbox and the autocomplete field.

My goal is to only display the selected results from the "select a content type" field onto the autocomplete field.

So when a user selects a "news" / "events" / "Product" / "image" from the "Select a content type" field, the autocomplete only displays nodes of what was selected. If I select news then only news appears when I start entering data. If I select News and events, then both will show. If I select none then a custom message appears.

I have looked around and found how to overwrite getReferenceableEntities but I don't see a way to pass two variables: one from the checkbox field and the autocomplete entered value.

I suspect there will be JS involved to have the form send both checkbox and search value over but I don't know where to begin.

2 comments

@Prestosaurus 2019-05-16 16:47:58

MYMODULE/src/EntityAutoCompleteMatcher.php:

class EntityAutocompleteMatcher extends \Drupal\Core\Entity\EntityAutocompleteMatcher {

  /**
   * Gets matched labels based on a given search string.
   */
  public function getMatches($target_type, $selection_handler, $selection_settings, $string = '') {

    $matches = [];

    $options = [
      'target_type'      => $target_type,
      'handler'          => $selection_handler,
      'handler_settings' => $selection_settings,
    ];

    $handler = $this->selectionManager->getInstance($options);

    if (isset($string)) {
      // Get an array of matching entities.
      $match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
      $entity_labels = $handler->getReferenceableEntities($string, $match_operator, 10);

      // Loop through the entities and convert them into autocomplete output.
      foreach ($entity_labels as $values) {
        foreach ($values as $entity_id => $label) {

          $entity = \Drupal::entityTypeManager()->getStorage($target_type)->load($entity_id);
          $entity = \Drupal::entityManager()->getTranslationFromContext($entity);

          // Only return bundle types we want.
          if ($entity->bundle() == 'page') {
            $matches[] = ['value' => $label, 'label' => $label];
          }
        }
      }
    }

    return $matches;
  }

}

More work would need to be done, but this shows where we can control the returned list of referenced entities.

See:

https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21EntityAutocompleteMatcher.php/8.8.x

@Francis Yaconiello 2019-05-16 00:09:41

I don't know the exact UX you are going for, but with a mix of conditional fields an entity reference view and some hook_views_pre_view I think you can accomplish what you need.

First create a new view that has a display that is an Entity Reference. see: How to create a view type of Entity reference display?

  • make sure that the Entity reference view filter returns the 4 content types you are interested in.
  • Add a contextual filter for the content type

Second, configure the node autocomplete field to use the content entity reference view as it's datasource

this is an example of configuring another node's field to use an entity reference view as a datasource

Note: if you are setting up your form some other way (its not a node form display) you'll have to set this up in code - i don't have an example handy.

Lastly, when the user makes a content type choice store that value somewhere (session, on the content, whatever) so that the choice is accessable via the hook_views_pre_view hook.

/**
 * Implements hook_views_pre_view().
 *
 * @param ViewExecutable $view
 * @param QueryPluginBase $query
 * @return void
 */
function MY_MODULE_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
  // Get the content type choice from wherever you stored it
  $content_type = "SOME_TYPE";
  // add a filter to the brand view for the supplier's ICs
  if($view->id() == 'MY_CUSTOM_VIEW' && $view->getDisplay()->display['id'] == 'entity_reference_1') {
      $args = [$content_type];
  }
}

@Simon Song 2019-05-16 15:11:02

Yesterday after posting my question I changed the reference method to use views and contextual filters. This Answer is perfect and does what I need except for the last part. I think this is the UX part you don't know about. The "content type choice" is on the same page as the autocomplete field. It may appear afterwards but once I add the autocomplete and the end user decides they need to change it then I want the autocomplete to reflect that. I feel like this hook may not work. Or am I wrong about that and the autocomplete always refer back to hook_views_pre_view()

@Francis Yaconiello 2019-05-16 16:47:43

so the autocomplete callback is an ajax to the resultset returned by this view. So if you've stored the user's content type choice somewhere that the hook can read from (session, cookie, formstate, whatever) then this hook should fire before returning results to the widget.

Related Questions

Sponsored Content

0 Answered Questions

0 Answered Questions

Using views field formatter with paragraphs

  • 2018-12-31 10:24:29
  • R. Schleutker
  • 152 View
  • 0 Score
  • 0 Answer
  • Tags:   views paragraphs

3 Answered Questions

[SOLVED] How to get paragraph field values?

1 Answered Questions

[SOLVED] Views block doesn't appear on page if only media-type content is selected

  • 2018-10-22 19:49:41
  • ACanadianCoder
  • 24 View
  • 0 Score
  • 1 Answer
  • Tags:   views 8 blocks

1 Answered Questions

[SOLVED] Custom validation for paragraph field

  • 2018-10-24 19:21:36
  • user3421014
  • 272 View
  • 0 Score
  • 1 Answer
  • Tags:   paragraphs

1 Answered Questions

[SOLVED] Limit amount of adding a certain Paragraph per Content type

2 Answered Questions

1 Answered Questions

Multilingual Paragraphs fields are not present in node content

1 Answered Questions

[SOLVED] How do I check the value of a Boolean field in a template file?

1 Answered Questions

[SOLVED] How to reference a specific field?

Sponsored Content