view popups_reference.module @ 4:9d5826d3028d

Put the wrapper code after the form has been build and elements replaced
author Franck Deroche <franck@defr.org>
date Mon, 26 Jan 2009 14:23:35 +0100
parents 98642e828c60
children 990f71344a66
line wrap: on
line source
<?php
// $Id: popups_reference.module,v 1.1.2.6 2009/01/18 22:40:33 starbow Exp $

/**
 * @file
 * Modify the Node Reference widget to use a popup to add a new node.
 */ 


/**
 * Implementation of hook_form_alter().
 * 
 * Modifies the nodereference setting form and the basic node form. 
 */
function popups_reference_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'content_field_edit_form') {
    // Add a checkbox to the nodereference settings page.
    $field_name = $form['#field']['field_name'];
    $form['field']['show_add_link'] = array(
    '#type' => 'checkbox',
      '#default_value' => variable_get('popups_reference_show_add_link_'. $field_name, TRUE),
      '#title' => t('Show the "Add New: Node Type" Popup links'),
      '#description' => t("Activate Popups:Add and Reference behavior for this reference.")
    );
    $form['#submit'][] = '_popups_reference_manage_fields_submit';
  }
  elseif (isset($form['type'])) {
    // Add the "Add New: Node Type" links.
    $node = $form['#node'];
    if ($form['type']['#value'] .'_node_form' == $form_id) {  
      $fields = content_fields();
      foreach ($form as $key => $item) {
        if (is_array($item)) {
          $type = $item['#type'];
          if ($type == 'fieldset') { // Loop through all the subitems.
            foreach ($form[$key] as $subkey => $subitem) {
              popups_reference_alter_item($form[$key], $subkey, $subitem, $fields);
            }
          }
          else {
            popups_reference_alter_item($form, $key, $item, $fields);
          }
        }
        
      }
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 * Add cookies with node info when a new node is created.
 * These cookies will be found by the popups_reference behavior and used
 *   to select the newly created node in the reference widget.
 */ 
function popups_reference_nodeapi($node, $op) {
  if ($op == 'insert') {
      $five = time()+300; // 5 minutes in the future.
      setcookie("PopupRefNid", $node->nid, $five, '/'); 
      setrawcookie("PopupRefTitle", rawurlencode($node->title), $five, '/');
  }
}

/**
 * Submit added to the the nodereference settings form.
 * Set a variable for each nodereference field.
 */
function _popups_reference_manage_fields_submit($form, &$form_state) {
  $field_name = $form['#field']['field_name'];
  variable_set('popups_reference_show_add_link_'. $field_name, $form_state['values']['show_add_link']);
}

/**
 * Run on every element in the basic node form.
 * Wrap the enabled nodereference fields, and add the popup links.
 *
 * @param $form - the form (or fieldgroup).
 * @param $key - form element name.
 * @param $item - the form element array.
 * @param $fields - all fields info.
 */
function popups_reference_alter_item(&$form, $key, $item, $fields) {  
  $field_name = strstr($key, 'field_'); // Check if $key starts with 'field_';
  if (isset($fields[$field_name]) && 
      $fields[$field_name]['type'] == 'nodereference' &&
      variable_get('popups_reference_show_add_link_'. $field_name, TRUE)) {
    $type = $form['type']['#value'];
    $field = content_fields($field_name, $form['type']['#value']);

    $wrapper_id = 'popups-reference-' . _popups_reference_counter();
    $links = _popups_reference_links($field, $type, $wrapper_id, $field['widget']['type']);
    if ($links) {
      // Put the nodereference widget and links in an wrapper.
      // Makes it easy to find for Ahah targeting, and popups_reference behavior selecting.
      $form[$key]['#popups_reference_prefix'] = '<div id="'. $wrapper_id .'">';
      $form[$key]['#popups_reference_suffix'] = '<div>Add New: ' . implode(', ', $links) .'</div></div>';
      $form[$key]['#after_build'][] = 'popups_reference_after_build';
    }
  }
}

function popups_reference_after_build($form_element) {
  $form_element['#prefix'] = $form_element['#popups_reference_prefix'] . $form_element['#prefix'];
  $form_element['#suffix'] .= $form_element['#popups_reference_suffix'];
  return $form_element;
}

/**
 * Generates 'Add new...' link
 * for each allowed content type
 *
 * @param $field
 * @param $src_type - the type of base node.
 * @param $wrapper_id - id for the wrapper around the node reference.
 * @param $type - the type of the node being referenced.
 * @return Array of html links.
 */
function _popups_reference_links($field, $src_type, $wrapper_id, $type) {
  if ($type == 'nodereference_select' || $type == 'nodereference_buttons') { 
    // Target the wrapper for replacing.
    popups_add_popups(array('a.'.$wrapper_id=>array('targetSelectors'=>array('#'.$wrapper_id))));
  }
  else if ($type == 'nodereference_autocomplete') { 
    // Don't replace the autocomplete when done.
    popups_add_popups(array('a.'.$wrapper_id=>array('noUpdate'=>TRUE)));
  }
  else { // Unsupported type.
    return;
  }
  $options = array(
    'attributes' => array(
      'class' => $wrapper_id . ' popups-reference', 
      'rel' => $wrapper_id,
  ),
    'query' => array('destination' => 'node/add/' . str_replace('_', '-', $src_type)),  
  );
  $links = array();
  $all_types = node_get_types();
  foreach ($field['referenceable_types'] as $add_type => $value) {
    if (!empty($value) && user_access("create $add_type content")) {
      drupal_add_js(drupal_get_path('module', 'popups_reference') .'/popups_reference.js');
      $path = 'node/add/' . str_replace('_', '-', $add_type);
      $links[] = l("Add $add_type", $path, $options);
    }
  }
  return $links;
}

/**
 * A counter for generating unique element id's.
 *
 * @return int: next integer.
 */
function _popups_reference_counter() {
  static $count = 0;
  return $count++;
}