You are here

theme.inc in Multifield table 7

Theme functions for the Mutifield Table module.

File

theme/theme.inc
View source
<?php

/**
 * @file
 * Theme functions for the Mutifield Table module.
 */

/**
 * Print a single row of multiple fields.
 */
function theme_multifield_table_multiple_value_field($variables) {
  $element = $variables['element'];
  $header = array();
  $cells = array();

  // Order field widgets by their widget weight.
  $instances = field_info_instances($element['#entity_type'], $element['#bundle']);
  uasort($instances, '_multifield_table_sort_items_widget_helper');
  foreach ($instances as $field_name => $instance) {
    if (empty($element[$field_name])) {
      continue;
    }
    $header[] = _multifield_table_get_title($element[$field_name]);
    $cells[] = array(
      'data' => $element[$field_name],
    );

    // Remove the original field to prevent duplicate printing.
    unset($element[$field_name]);
  }
  $element['multifield_table'] = array(
    '#theme' => 'table',
    '#header' => $header,
    '#rows' => array(
      $cells,
    ),
    '#weight' => 0,
  );
  $element['#sorted'] = FALSE;
  return drupal_render_children($element);
}

/**
 * Comparison function for sorting field instances by their widget's weight.
 */
function _multifield_table_sort_items_widget_helper($a, $b) {
  $a_weight = is_array($a) && isset($a['widget']['weight']) ? $a['widget']['weight'] : 0;
  $b_weight = is_array($b) && isset($b['widget']['weight']) ? $b['widget']['weight'] : 0;
  return $a_weight - $b_weight;
}

/**
 * Replacement for theme_field_multiple_value_form().
 *
 * Each field is printed in a separate cell.
 */
function theme_multifield_table_multiple_value_fields($variables) {
  $element = $variables['element'];
  $output = '';
  if (isset($element['#cardinality']) && ($element['#cardinality'] > 1 || $element['#cardinality'] == FIELD_CARDINALITY_UNLIMITED)) {
    $table_id = drupal_html_id($element['#field_name'] . '_values');
    $order_class = $element['#field_name'] . '-delta-order';
    $required = !empty($element['#required']) ? '<span class="form-required" title="' . t('This field is required.') . '">*</span>' : '';
    $rows = array();

    // Sort items according to '_weight' (needed when the form comes back after
    // preview or failed validation).
    $items = array();
    foreach (element_children($element) as $key) {
      if ($key === 'add_more') {
        $add_more_button =& $element[$key];
      }
      else {
        $items[] =& $element[$key];
      }
    }
    usort($items, '_field_sort_items_value_helper');
    $header = array(
      array(
        'data' => '<label>' . t('!title: !required', array(
          '!title' => $element['#title'],
          '!required' => $required,
        )) . "</label>",
        'class' => array(
          'field-label',
        ),
      ),
    );
    $id_fields = array(
      '#type' => 'container',
      '#attributes' => array(),
    );

    // Add the items as table rows.
    foreach ($items as $key => $item) {

      // Make sure _weight comes after actions.
      $item['_weight']['#weight'] = 101;
      uasort($item, 'element_sort');
      $item['_weight']['#attributes']['class'] = array(
        $order_class,
      );
      $cells = array(
        array(
          'data' => '',
          'class' => array(
            'field-multiple-drag',
          ),
        ),
      );
      foreach (element_children($item) as $field_name) {
        if ($field_name != 'id') {

          // Only add the header once.
          if ($key == 0) {
            $header[] = array(
              'data' => '<label>' . t('!title', array(
                '!title' => _multifield_table_get_title($item[$field_name]),
              )) . '</label>',
              'class' => array(
                'field-label',
              ),
            );
          }
          $cells[] = array(
            'data' => $item[$field_name],
          );
        }
        else {
          $id_fields[] = $item[$field_name];
        }
      }
      $rows[] = array(
        'data' => $cells,
        'class' => array(
          'draggable',
        ),
      );
    }
    $output = array(
      '#prefix' => '<div class="form-item">',
      '#suffix' => '</div>',
    );
    $output['multifield_table'] = array(
      '#theme' => 'table',
      '#header' => $header,
      '#rows' => $rows,
      '#attributes' => array(
        'id' => $table_id,
        'class' => array(
          'field-multiple-table',
        ),
      ),
    );
    if (!empty($element['#description'])) {
      $output[] = array(
        '#prefix' => '<div class="description">',
        '#suffix' => '</div>',
        '#markup' => $element['#description'],
      );
    }
    if (isset($add_more_button)) {
      $output[] = $add_more_button + array(
        '#prefix' => '<div class="clearfix">',
        '#suffix' => '</div>',
      );
    }
    if (!empty($id_fields)) {
      $output[] = $id_fields;
    }
    $output = drupal_render($output);
    drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class);
  }
  else {
    foreach (element_children($element) as $key) {
      $output .= drupal_render($element[$key]);
    }
  }
  return $output;
}

/**
 * Implements template_preprocess_table__multifield_table().
 */
function template_preprocess_table__multifield_table(&$variables) {
  if (empty($variables['settings'])) {
    return;
  }
  if (isset($variables['settings']['empty'])) {
    _multifield_table_hide_empty($variables);
  }
}

/**
 * Remove columns that are entirely empty.
 */
function _multifield_table_hide_empty(&$variables) {
  $rows = $variables['rows'];
  $count = array();
  foreach ($rows as $row_delta => $row) {
    foreach ($row['data'] as $column_delta => $column) {
      if (!isset($count[$column_delta])) {
        $count[$column_delta] = 0;
      }
      if (isset($column['data']['#empty'])) {
        $count[$column_delta]++;
      }
    }
  }
  foreach ($count as $column_delta => $column) {
    if ($column === count($rows)) {
      foreach ($rows as $row_delta => $row) {
        unset($variables['rows'][$row_delta]['data'][$column_delta]);
        unset($variables['header'][$column_delta]);
      }
    }
  }
}

/**
 * Derivative of theme_table() solely for the HOOK_preprocess_table__PATTERN().
 */
function theme_table__multifield_table($variables) {
  return theme_table($variables);
}

/**
 * Helps find the title of the field, as it could be in several places.
 */
function _multifield_table_get_title($field) {
  $title = '';
  if (isset($field['#language']) && isset($field[$field['#language']])) {
    $language = $field['#language'];
    if (isset($field[$language]['#title'])) {
      $title = $field[$language]['#title'];
    }
    elseif (isset($field[$language][0]['#title'])) {
      $title = $field[$language][0]['#title'];
    }
    elseif (isset($field[$language][0])) {
      foreach (element_children($field[$language][0]) as $child) {
        if (isset($field[$language][0][$child]['#title'])) {
          $title = $field[$language][0][$child]['#title'];
          break;
        }
      }
    }
  }
  elseif (isset($field['#title'])) {
    $title = empty($field['#is_weight']) ? $field['#title'] : t('Order');
  }
  elseif (isset($field['#value'])) {
    $title = $field['#value'];
  }
  return $title;
}

Functions

Namesort descending Description
template_preprocess_table__multifield_table Implements template_preprocess_table__multifield_table().
theme_multifield_table_multiple_value_field Print a single row of multiple fields.
theme_multifield_table_multiple_value_fields Replacement for theme_field_multiple_value_form().
theme_table__multifield_table Derivative of theme_table() solely for the HOOK_preprocess_table__PATTERN().
_multifield_table_get_title Helps find the title of the field, as it could be in several places.
_multifield_table_hide_empty Remove columns that are entirely empty.
_multifield_table_sort_items_widget_helper Comparison function for sorting field instances by their widget's weight.