Introduction

The atom reference modules provides a field where atoms can be drag and dropped from the library. This allows the user to make a reference from any entity where the field has been inserted to an atom or a list of atoms. This can per example be used to create a media gallery.

PHP

Core hooks used

hook_field_info() :
Define the field information see api documentation.

hook_field_instance_settings_form() :
Field properties for the form when the field is added to an entity. See api documentation.

hook_field_schema() :
Defines the field database column. We use only one, the atom sid. Please see hook field schema

hook_field_validate() :
We check that the referenced atoms type is in the list of type that is allowed for the field.api documentation

hook_field_is_empty() :
We return an empty value. Check api documentation.

hook_field_formatter_info() :
We define scald display context as formatters for the field. Check api documentation.

hook_field_formatter_view() :
We send the rendering of the element thru the scald core function scald_render, passing the display context. See api documentation.

hook_field_widget_info() :
We expose the widget for the entity form. In our case this is a drop box where atoms will be drag and dropped. api documentation.

hook_field_widget_form() :
We first enable the atom library ( library module ) and then define the field item :

  $return['sid'] = $element;
  $return['sid']['#description'] .= $help;

  $return['sid']['#type'] = 'textfield';
  // $options is an array of the referencable atom types in the field.
  $return['sid']['#attributes'] = array('data-types' => implode(',', array_keys($options)));
  $return['sid']['#default_value'] = isset($items[$delta]) ? $items[$delta]['sid'] : '';

  $return['sid']['#process'][] = 'atom_reference_field_widget_form_process';

  // Attach our JS and CSS to the element
  $path = drupal_get_path('module', 'atom_reference');
  $return['sid']['#attached'] = array(
    'css' => array($path . '/atom_reference.css'),
    'js'  => array($path . '/atom_reference.js')
  );
 return $return;

hook_field_widget_error() :
Set a form_set_error message. api documentation.

Views hook

hook_field_views_data() :
This hook is provided by the views module, see views documentation. This allows us to register the atom reference to views.

Function

atom_reference_field_widget_form_process(&$element) :
This is the actual processing of the field. This is launched by

$return['sid']['#process'][] = 'atom_reference_field_widget_form_process';

We send per default the placeholder of the field or the value of the atom in this display context mode :

  $default = $element['#value'];
  if ($default) {
    $prefix = '<div class="atom_reference_drop_zone">' . scald_render($default, 'sdl_editor_representation') .'</div>';
  }
  else {
    $placeholder = t('Drop a resource here');
    $prefix = '<div class="atom_reference_drop_zone"><em>' . $placeholder . '</em></div>';
  }
  $element['#field_prefix'] = $prefix;
  return $element;

Javascript

The javascript is located in atom_reference.js.
We define a namespace in drupal behaviors array : Drupal.behaviors.atom_reference.
We mainly manage the field via javascript, appending in editor display context the atom the necessary HTML. We also manage the deletion of an atom.
javascript to append an atom :

 $this
    // we add a class to show that it is processed
    .addClass('atom_reference_processed')
    // drag and drop function
    .bind('dragover', function(e) {e.preventDefault();})
    .bind('dragenter', function(e) {e.preventDefault();}) 
    // on drop
    .bind('drop', function(e) {
     var dt = e.originalEvent.dataTransfer.getData('Text').replace(/^\[scald=(\d+).*$/, '$1');
      var ret = Drupal.atom_reference.droppable(dt, this);
      var $this = $(this);
      // the atom is good to be dropped in the field
      if (ret.found && ret.keepgoing) {
        $this
          .empty()
          //append atom editor representation html
          .append(Drupal.dnd.Atoms[dt].editor)
          .closest('div.form-item')
          .find('input:text')
          // add the sclad sid in the form element
          .val(dt)
          .end()
          .find('input:button')
          .show();
      }

Form API
The Atom reference field is also usable through the Form API.

$types = scald_types();
$form['scald_atom'] = array(
    '#type' => 'textfield',
    '#title' => t('Scald atom'),
    '#description' => t(''),
    '#default_value' => $default_value,
    '#attached' => array(
      'library' => array(
        array('dnd', 'library'),
        array('atom_reference', 'library'),
      ),
    ),
    '#attributes' => array(
      'data-types' => implode(',', array_keys($types)),
      'data-dnd-context' => 'sdl_editor_representation',
    ),
    '#preview_context' => 'sdl_editor_representation',
    '#process' => array('atom_reference_field_widget_form_process'),
  );

Comments

amittarkar’s picture

where is the download link for this module?

marcvangend’s picture

These are all part of the Scald project, http://drupal.org/project/scald.