Better UX in your forms, the easy way

Entity References are cool. Prepopulating them is even cooler. You've seen it already, but if you are not working with Field API, you're on your own... until now, at least.

Photo of Salvador Molina Moreno
Mon, 2014-06-23 09:18By salva

If you've ever used Organic Groups, chances are that you have come across the Entity Reference Prepopulate module. If not, you might still have come across it, since it's a well known module, incredibly useful to prepopulate some node or entity fields on forms when certain arguments are present in the URL of those forms. I've always loved that small improvement to User Experience in Drupal forms: Why make users populate some fields when the value could be figured out from the context in which they're performing a given task?

About a year ago, we contributed back to the community, the Entity Reference Autocomplete module, which we've used in some projects now, and quite extensively in particularly one of them. And in that one, the mentioned prepopulate feature would have been a perfect match. However, as with some other modules that leverage the Entity Reference module, this one wasn't suitable for non Field API fields, or, in other words, with custom forms. 

So we built a small module to bridge that gap, which can be found at our github account. As its name suggests, the ERP Bridge (Entity Reference Prepopulate Bridge), is just that, a simple bridge module, or wrapper, to make easy the use of the Prepopulate module on custom forms. So how do you use it? Simple. Let's say you have a custom form with a field called project_id which is a reference to a "Project" entity. First, you need to define a form property called "#erp_bridge_fields", like:

$form['#erp_bridge_fields'] = array();

Then, inside that, include an array of settings for each field to be prepopulated of your form. Assuming you only have the mentioned project_id:

  $form['#erp_bridge_fields']['project_id'] = array(
      'target_type' => 'project',
      'entity_type' => 'form-entity-type',
      'bundle' => 'form-entity-bundle',
      'target_bundles' => array(),
      'prepopulate_settings' => array(),
  );

Target_type is the type of entity you're referencing. It's mandatory, and without that, the prepopulate magic will simply not happen. For entity_type and bundle, those refer to the "entity from which the reference is being made", but they can actually be set to any value of existing entities and bundles in the system, since the prepopulate module doesn't actually use them (at least, not the bundle). But if your form is for a custom entity, better to specify them. If you want to restrict the reference to any given bundles, specify then in target_bundles property. And finally, use prepopulate_settings to specify how the form should behave when prepopulated (i.e: hiding the prepopulated value or disabling it, etc). To see the full picture of what you can do with them, better check the README of the prepopulate module itself! 

After  you've defined your prepopulated fields, just call this function with the specified parameters, before returning the $form array of your form:

erp_bridge_prepopulate_form($form, $form_state);

That will wrap your settings with the form elements affected, and pass them on to the Entity Reference Prepopulate module as it expects them, to make it work. After that, the only bit to mention is that the URL parameters from which the values will be picked up, have to match the field name of the affected field on your form. For this example, you'd have to assemble your form URL with something similar to "/path-to-your-form?project_id=xxx". And that's it, the propulate should be able to do its magic to add some better UX to your form.

Yes, it could be simpler, and it could be integrated within the prepopulate module or the autocomplete module itself (and it might be at some point), but back in the day when we did this there were some other constraints, so the decision was to go with a quick solution to simply close the gap. So, if you're using the autocomplete module on your forms and would like this functionality, don't hesitate, head over to our github account and help yourself!