By neemu


2016-01-24 01:35:10 8 Comments

I'll like to add this functionality to the autocomplete widget in Entityreference field to show node ID next to the titles in the dropdown list. The reason behind the idea is to differentiate between multiple nodes with same title.

Example:

  • This is a title (3)
  • This is a title (2)
  • This is a title (1)

I know the node ID is shown once a selection is made but I like to show it in the dropdown list in order to pick the right node quickly based on the node ID.

2 comments

@Adrian Cid Almaguer 2016-01-24 22:07:30

Install the Views and Entity Reference modules, create a new View and Add a Entity Reference Display:

enter image description here

Then Add in the fields the content title and the nid, click in the nid and check Exclude from display, Save and click in the title and go to rewrite the output of the title as [title] - ([nid])

enter image description here enter image description here

Go to edit the settings of the format and check the title, this will allow you to search by title.

enter image description here

Save the view.

Go to edit your Entity Reference field and select in the Mode Views: .... (like the following image) and select your View (in this case the name is: articles_with_id) and save the settings:

enter image description here

Then go to see the result:

enter image description here

EDIT: This is now working in Drupal 8, at least in the version 8.3.4.

@No Sssweat 2016-01-25 07:23:28

OMG, I always wondered what the views option was for. This is filthy!!!

@Adrian Cid Almaguer 2016-01-25 14:36:36

@NoSssweat I'm learning english now, can you provide me a synonym of filthy please? I can't understand the phrase "This is filthy"

@No Sssweat 2016-01-25 19:29:04

Synonym: Dirty. I used it as an expression, should be taken figuratively and not literally.

@Adrian Cid Almaguer 2016-01-25 19:41:44

@NoSssweat Then is a bad solution?

@No Sssweat 2016-01-25 19:49:42

No, it means it's a really good/impressive solution. Ex: Alexander Nylander's Filthy Shootout Goal

@Adrian Cid Almaguer 2016-01-25 20:07:58

@NoSssweat thanks, I learning English too in this site ;-)

@John R 2016-02-02 10:55:00

@AdrianCidAlmaguer I agree this solution is "sick"! (idiom)

@Adrian Cid Almaguer 2016-02-02 18:13:52

@JohnR is sick in a good way or in a bad way? Remember that I learning english now, and sick is unwell, this confuse me a little ;-)

@Yuri 2016-05-26 15:29:55

The only problem with this solution, is that the entity reference field, once selected, shows the ID twice in the entity edit form, because it is included by default once it is selected.

@Adrian Cid Almaguer 2016-05-26 16:08:39

@Yuri Yes, I will see if I find a solution for this. thanks

@Shawn Matthews 2017-05-01 19:48:49

Does anyone know if this works for the user entity as well. No matter how I seem to set it up it always displays the email address (user) and not firstname / lastname from the associated user entity. Great walk through btw!

@Adrian Cid Almaguer 2017-05-01 19:58:01

@ShawnMatthews I think that will work, but I never made the test, you can follow the steps and test with users, if this works share here your results ;-)

@Shawn Matthews 2017-05-01 20:24:06

Incase anyone stumbles across this. Its currently broken in 8.0+ drupal.org/node/2174633

@Adrian Cid Almaguer 2017-07-06 15:47:46

@ShawnMatthews this is now working in drupal 8.3.4

@armyofda12mnkeys 2019-03-29 14:34:44

@AdrianCidAlmaguer Im using Drupal 8.6+patch in above url (if I click 'Add Existing Badge', the entity view/autocomplete works). But I'm curious y this dropdown shows in the field's display: farm8.staticflickr.com/7856/46769243104_db4bcfa2e6_z.jpg If I change the field to use the 'Default' Reference Method and pick my 'Badge' type, then there is no dropdown. Settings for that: farm8.staticflickr.com/7816/47492694801_abd94f7970_z.jpg vs settings for Entity Ref field which causes the dropdown to show up: farm8.staticflickr.com/7909/46577339485_e124628460_z.jpg

@armyofda12mnkeys 2019-03-29 14:43:35

Adding to my above comment... in the 'Manage form display' settings of the Badge content type, the "Allow users to add new badges#2" is what adds that dropdown. its smart to recognize to only use Badge content type in the 'Add Existing' autocomplete since my entity ref view specifically filters on Badges, but the 'Add new' button doesn't use this view reference im guessing (since its not an autocomplete), so have to manually pick which content type you want to add. I wonder if there is a fix for this (like a way in the field settings to say 'use Badges in with Add New functionality')

@Adrian Cid Almaguer 2019-03-30 18:47:57

@armyofda12mnkeys I really don't know, I'm not working with this feature now.

@No one 2016-01-29 09:09:28

Create Entity Reference field with the default configuration

enter image description here

The function entityreference_autocomplete_callback_get_matches determines what the output of the autocomplete should be.

function entityreference_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
  $matches = array();

  $entity = NULL;
  if ($entity_id !== 'NULL') {
    $entity = entity_load_single($entity_type, $entity_id);
    $has_view_access = (entity_access('view', $entity_type, $entity) !== FALSE);
    $has_update_access = (entity_access('update', $entity_type, $entity) !== FALSE);
    if (!$entity || !($has_view_access || $has_update_access)) {
      return MENU_ACCESS_DENIED;
    }
  }

  $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);

  if ($type == 'tags') {
    // The user enters a comma-separated list of tags. We only autocomplete the last tag.
    $tags_typed = drupal_explode_tags($string);
    $tag_last = drupal_strtolower(array_pop($tags_typed));
    if (!empty($tag_last)) {
      $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
    }
  }
  else {
    // The user enters a single tag.
    $prefix = '';
    $tag_last = $string;
  }

  if (isset($tag_last)) {
    // Get an array of matching entities.
    $entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10);

    // Loop through the products and convert them into autocomplete output.
    foreach ($entity_labels as $values) {
      foreach ($values as $entity_id => $label) {
        $key = "$label ($entity_id)";
        // Strip things like starting/trailing white spaces, line breaks and tags.
        $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key)))));
        // Names containing commas or quotes must be wrapped in quotes.
        if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
          $key = '"' . str_replace('"', '""', $key) . '"';
        }
        /* *** */$matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .' - ('. $entity_id . ')</div>';//****
      }
    }
  }
  drupal_json_output($matches);
}

the last line $matches[$prefix . $key] = '<div class="reference-autocomplete">' determines the output and the $entity_id is available which is the ID. You can do what I did in that line (shown by **), simply write:

 $matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .' - ('. $entity_id . ')</div>';

you can use $entity_id to fetch other fields and anything you want.

One More Thing!

Some times it is not a good idea to change the function of the core module (if it is not important to you the above solution is enough).

If you need to override the core function of the entity_reference module, build a small module and name it elabel

it is elabel.info

;$Id;
name = My Entity Reference Label
description = This module creates special Entity Reference Label
package = My Modules
core = 7.x
php = 5.1
files[] = elabel.module

and it is elabel.module

<?php function elabel_menu_alter(&$items){
    unset($items['entityreference/autocomplete/single/%/%/%']);
    unset($items['entityreference/autocomplete/tags/%/%/%']);

      $items['entityreference/autocomplete/single/%/%/%'] = array(
    'title' => 'Entity Reference Autocomplete',
    'page callback' => 'elabel_autocomplete_callback',
    'page arguments' => array(2, 3, 4, 5),
    'access callback' => 'entityreference_autocomplete_access_callback',
    'access arguments' => array(2, 3, 4, 5),
    'type' => MENU_CALLBACK,
  );

    $items['entityreference/autocomplete/tags/%/%/%'] = array(
    'title' => 'Entity Reference Autocomplete',
    'page callback' => 'elabel_autocomplete_callback',
    'page arguments' => array(2, 3, 4, 5),
    'access callback' => 'entityreference_autocomplete_access_callback',
    'access arguments' => array(2, 3, 4, 5),
    'type' => MENU_CALLBACK,
  );
  return $items;

}

function elabel_autocomplete_callback($type, $field_name, $entity_type, $bundle_name, $entity_id = '', $string = '') {
  // If the request has a '/' in the search text, then the menu system will have
  // split it into multiple arguments and $string will only be a partial. We want
  //  to make sure we recover the intended $string.
  $args = func_get_args();
  // Shift off the $type, $field_name, $entity_type, $bundle_name, and $entity_id args.
  array_shift($args);
  array_shift($args);
  array_shift($args);
  array_shift($args);
  array_shift($args);
  $string = implode('/', $args);

  $field = field_info_field($field_name);
  $instance = field_info_instance($entity_type, $field_name, $bundle_name);

  return elabel_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id, $string);
}

function elabel_autocomplete_callback_get_matches($type, $field, $instance, $entity_type, $entity_id = '', $string = '') {
  $matches = array();

  $entity = NULL;
  if ($entity_id !== 'NULL') {
    $entity = entity_load_single($entity_type, $entity_id);
    $has_view_access = (entity_access('view', $entity_type, $entity) !== FALSE);
    $has_update_access = (entity_access('update', $entity_type, $entity) !== FALSE);
    if (!$entity || !($has_view_access || $has_update_access)) {
      return MENU_ACCESS_DENIED;
    }
  }

  $handler = entityreference_get_selection_handler($field, $instance, $entity_type, $entity);

  if ($type == 'tags') {
    // The user enters a comma-separated list of tags. We only autocomplete the last tag.
    $tags_typed = drupal_explode_tags($string);
    $tag_last = drupal_strtolower(array_pop($tags_typed));
    if (!empty($tag_last)) {
      $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
    }
  }
  else {
    // The user enters a single tag.
    $prefix = '';
    $tag_last = $string;
  }

  if (isset($tag_last)) {
    // Get an array of matching entities.
    $entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'], 10);

    // Loop through the products and convert them into autocomplete output.
    foreach ($entity_labels as $values) {
      foreach ($values as $entity_id => $label) {
        $key = "$label ($entity_id)";
        // Strip things like starting/trailing white spaces, line breaks and tags.
        $key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(decode_entities(strip_tags($key)))));
        // Names containing commas or quotes must be wrapped in quotes.
        if (strpos($key, ',') !== FALSE || strpos($key, '"') !== FALSE) {
          $key = '"' . str_replace('"', '""', $key) . '"';
        }
        /* *** */ $matches[$prefix . $key] = '<div class="reference-autocomplete">' . $label .'('.$entity_id.')' .'</div>';
      }
    }
  }

  drupal_json_output($matches);
}

I tried this code and it works perfectly If there are other type of entity references and you don't need to do this for them, simply add an IF statement and check for bundle or content type.

Related Questions

Sponsored Content

1 Answered Questions

Node select list + dropdown + view of entity references

  • 2018-03-30 08:04:21
  • Frederic Dessy
  • 91 View
  • 0 Score
  • 1 Answer
  • Tags:   7 views entities

1 Answered Questions

[SOLVED] Entity reference item list with preview images?

  • 2015-07-15 12:26:25
  • tillinberlin
  • 341 View
  • 0 Score
  • 1 Answer
  • Tags:   entities

1 Answered Questions

[SOLVED] I want to override results of an autocomplete field (Entity reference in a content)

  • 2016-09-02 17:09:47
  • Anis Taktak
  • 1162 View
  • 1 Score
  • 1 Answer
  • Tags:   views 8 ajax

0 Answered Questions

Show more in Autocomplete reference content than the title (id)

1 Answered Questions

[SOLVED] Drupal 7, Entity Reference user autocomplete field

  • 2014-09-08 05:26:34
  • John R
  • 772 View
  • 0 Score
  • 1 Answer
  • Tags:   ajax entities

0 Answered Questions

Entity Reference Autocomplete on 2 fields entity

1 Answered Questions

Node Reference input with HTML preview

  • 2013-01-18 23:47:57
  • Godwin
  • 151 View
  • 0 Score
  • 1 Answer
  • Tags:   7 views nodes ajax

1 Answered Questions

2 Answered Questions

[SOLVED] Node reference autocomplete views issue

  • 2011-04-12 14:50:35
  • eggplant_casserole
  • 1555 View
  • 2 Score
  • 2 Answer
  • Tags:   6 views nodes

Sponsored Content