8

I am trying to override an entityreference autocomplete form item, I have managed to override the form, and get the arg passed to a hook_menu callback. However, I'm struggling with getting the callback to work based on what I type into the form box. Looking in the Entity reference module there is some code in the hook_autocomplete_callback that handles the $string argument and looks up matches $entity_labels = $handler->getReferencableEntities($tag_last, $instance['widget']['settings']['match_operator'] - something like that.

Can anyone assist?

My code:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function wl_event_form_event_node_form_alter(&$form, &$form_state, $form_id) {
  dpm($form);
  // We will get our term id argument from the from build itself.
    $node_id  = $form['#node']->nid;
  // This is the path we will create in hook_menu().
     $new_path = "wl_event/autocomplete/{$node_id}";
  // Maximum number of descrete values (deltas) that are present.
 $max_delta = $form['field_wl_event_acquired_resource']['und']['#max_delta'];
  // Hijack the autocomplete callback for each of our values.
  for($x=0; $x <= $max_delta; $x++) {
    $form['field_wl_event_acquired_resource']['und'][$x]['target_id']['#autocomplete_path']= $new_path;
  }
}

/**
 * Implements hook_menu().
 */
// can be used to do a lookup on a menu path to return json
// probably entity reference autocomplete does a similar thing

//we want to get all of the resources of the user profiles of
//users who are registered on the event

//
function wl_event_menu() {
  $items = array();
  $items['wl_event/autocomplete/%'] = array(
    'title' => t('project call back'),
    'page callback' => 'wl_event_autocomplete_callback',
    'page arguments' => array(2),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK
  );
  return $items;
}

function wl_event_autocomplete_callback($arg1, $string = '') {
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
  ->entityCondition('bundle', 'resource');
  // ->propertyCondition('nid', '1')
  $results = $query->execute();
  print_r(drupal_json_output($results));
  return drupal_json_output($results);
}
  • How do I interface with the lookup and output new content. I have checked out the code in entityference module, but I couldn't get it do what I wanted. My aim is to look up those are are registered through entity registration on the node which the autocomplete field is attached to, then do a query on another node called 'resources' which have been created by each one of the users that is registered.Thanks. – Andrew Welch Aug 13 '13 at 14:48
  • Code in entityreference that usually does this is entityreference_autocomplete_callback_get_matches() in drupalcode.org/project/entityreference.git/blob/HEAD:/… – Andrew Welch Aug 13 '13 at 15:44
  • as far as I can see (with some newly gained info just now), the callback is fired every time a user adds a new character into the autcomplete path, so whatever is in the callback should take the value entered and do the lookup and return the json. – Andrew Welch Aug 13 '13 at 16:55
10
+50

EntityReference uses the ctools plugin system to define selection handlers which feed into the autocomplete options. The interface definition is defined in entityreference/plugins/selection/abstract.inc. In that same directory, you will see the two included handlers, Simple and Views. Each of these is defined by two files, one for the class itself, and one with an array to register the plugin with ctools.

To provide your own selection handler, first tell ctools where to look for your plugin by implementing hook_ctools_plugin_directory.

/**
 * Implements hook_ctools_plugin_directory().
 */
function wl_event_ctools_plugin_directory($module, $plugin) {
  if ($module == 'entityreference') {
    return 'plugins/' . $plugin;
  }
}

Then create 2 files in wl_event/plugins/selection similar to those in the entityreference. The .inc file should define the ctools plugin info, and the .class.php file should contain your plugin class. Most likely you'll want to subclass EntityReference_SelectionHandler_Generic and just override the appropriate methods.

Lastly, make sure you add the file with your plugin class to the files[] array in your modules info file so that the autoloader can find it.

  • sounds good to me. Anyone else want to comment / answer before I give the bounty? – Andrew Welch Aug 15 '13 at 16:54
  • I have created the files and classes, my class extending the original class, but my plugin class never gets selected. Can you please edit your answer and expand the part? Should I somehow indicate that my class should be preferred to the original one? – Alexei Rayu Jan 31 '16 at 8:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.