You are here

function physical_field_widget_form in Physical Fields 7

Implements hook_field_widget_form().

File

./physical.module, line 237
Defines fields (e.g. weight and dimensions) to support describing the physical attributes of entities.

Code

function physical_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $widget = $instance['widget'];
  $settings = array_merge(field_info_widget_settings($widget['type']), $widget['settings']);

  // Widget for volume input.
  if ($widget['type'] == 'physical_volume_input') {

    // Determine the default volume value.
    if (isset($items[$delta]['volume'])) {
      $volume = round($items[$delta]['volume'], 5);
    }
    elseif (isset($instance['default_value'][0]['volume']) && ($delta == 0 || $field['cardinality'] > 0)) {
      $volume = round($instance['default_value'][0]['volume'], 5);
    }
    else {
      $volume = '';
    }

    // Add a textfield for the actual volume value.
    $element['volume'] = array(
      '#type' => 'textfield',
      '#title' => $element['#title'],
      '#default_value' => $volume,
      '#size' => 15,
      '#maxlength' => 16,
      '#required' => $instance['required'] && ($delta == 0 || $field['cardinality'] > 0),
    );

    // Determine the unit of measurement.
    if (!empty($items[$delta]['unit'])) {
      $unit = $items[$delta]['unit'];
    }
    elseif (!empty($settings['unit_select_list']) && !empty($instance['default_value'][0]['unit'])) {
      $unit = $instance['default_value'][0]['unit'];
    }
    else {
      $unit = $settings['default_unit'];
    }

    // If the user cannot select a different unit of measurement and the current
    // unit is the same as the default...
    if (empty($settings['unit_select_list']) && $unit == $settings['default_unit']) {

      // Display the unit of measurement after the textfield.
      $element['volume']['#field_suffix'] = physical_volume_unit_abbreviation($unit);
      if (!empty($element['#description'])) {
        $element['volume']['#suffix'] = '<div class="description">' . $element['#description'] . '</div>';
      }

      // Add a hidden value for the default unit of measurement.
      $element['unit'] = array(
        '#type' => 'value',
        '#value' => $unit,
      );
    }
    else {

      // Get an options list of volume units of measurement.
      $options = physical_volume_unit_options(FALSE);

      // If the user isn't supposed to have access to select a unit of
      // measurement, only allow the default and the current unit.
      if (empty($settings['unit_select_list'])) {
        $options = array_intersect_key($options, drupal_map_assoc(array(
          $unit,
          $settings['default_unit'],
        )));
      }

      // Display a unit of measurement select list after the textfield.
      $element['#attached']['css'][] = drupal_get_path('module', 'physical') . '/theme/physical.css';
      $element['volume']['#prefix'] = '<div class="physical-volume-input">';
      $element['unit'] = array(
        '#type' => 'select',
        '#options' => $options,
        '#default_value' => $unit,
        '#suffix' => '</div>',
      );
      if (!empty($element['#description'])) {
        $element['unit']['#suffix'] = '<div class="description">' . $element['#description'] . '</div></div>';
      }
      else {
        $element['unit']['#suffix'] = '</div>';
      }
    }
    return $element;
  }

  // Return the weight textfield widget.
  if ($widget['type'] == 'physical_weight_textfield') {

    // Determine the default weight value.
    if (isset($items[$delta]['weight'])) {
      $weight = round($items[$delta]['weight'], 5);
    }
    elseif (isset($instance['default_value'][0]['weight']) && ($delta == 0 || $field['cardinality'] > 0)) {
      $weight = round($instance['default_value'][0]['weight'], 5);
    }
    else {
      $weight = '';
    }

    // Add a textfield for the actual weight value.
    $element['weight'] = array(
      '#type' => 'textfield',
      '#title' => $element['#title'],
      '#default_value' => $weight,
      '#size' => 15,
      '#maxlength' => 16,
      '#required' => $instance['required'] && $delta == 0,
    );

    // Determine the unit of measurement.
    if (!empty($items[$delta]['unit'])) {
      $unit = $items[$delta]['unit'];
    }
    elseif (!empty($settings['unit_select_list']) && !empty($instance['default_value'][0]['unit'])) {
      $unit = $instance['default_value'][0]['unit'];
    }
    else {
      $unit = $settings['default_unit'];
    }

    // If the user cannot select a different unit of measurement and the current
    // unit is the same as the default...
    if (empty($settings['unit_select_list']) && $unit == $settings['default_unit']) {

      // Display the unit of measurement after the textfield.
      $element['weight']['#field_suffix'] = physical_weight_unit_abbreviation($unit);
      if (!empty($element['#description'])) {
        $element['weight']['#suffix'] = '<div class="description">' . $element['#description'] . '</div>';
      }

      // Add a hidden value for the default unit of measurement.
      $element['unit'] = array(
        '#type' => 'value',
        '#value' => $unit,
      );
    }
    else {

      // Get an options list of weight units of measurement.
      $options = physical_weight_unit_options(FALSE);

      // If the user isn't supposed to have access to select a unit of
      // measurement, only allow the default and the current unit.
      if (empty($settings['unit_select_list'])) {
        $options = array_intersect_key($options, drupal_map_assoc(array(
          $unit,
          $settings['default_unit'],
        )));
      }

      // Display a unit of measurement select list after the textfield.
      $element['#attached']['css'][] = drupal_get_path('module', 'physical') . '/theme/physical.css';
      $element['weight']['#prefix'] = '<div class="physical-weight-textfield">';
      $element['unit'] = array(
        '#type' => 'select',
        '#options' => $options,
        '#default_value' => $unit,
        '#suffix' => '</div>',
      );
      if (!empty($element['#description'])) {
        $element['unit']['#suffix'] = '<div class="description">' . $element['#description'] . '</div></div>';
      }
    }
    return $element;
  }

  // Return the dimensions textfields widget.
  if ($widget['type'] == 'physical_dimensions_textfields') {

    // Determine the default dimensions value.
    $value = array();
    if (isset($items[$delta]['length'])) {
      $value = array(
        'length' => round($items[$delta]['length'], 5),
        'width' => round($items[$delta]['width'], 5),
        'height' => round($items[$delta]['height'], 5),
        'unit' => $items[$delta]['unit'],
      );
    }
    elseif (isset($instance['default_value'][0]['length']) && ($delta == 0 || $field['cardinality'] > 0)) {
      $value = $instance['default_value'][0];
      if (empty($settings['unit_select_list'])) {
        unset($value['unit']);
      }
    }

    // Ensure the value array defines every expected key.
    foreach (physical_dimensions() as $key => $dimension) {
      $value += array(
        $key => '',
      );
    }
    $value += array(
      'unit' => $settings['default_unit'],
    );

    // Add textfields for the dimensions values.
    $element['#type'] = 'fieldset';
    $element['#attributes']['class'][] = 'physical-dimensions-textfields';
    $element['#attached']['css'][] = drupal_get_path('module', 'physical') . '/theme/physical.css';
    foreach (physical_dimensions() as $key => $dimension) {
      $element[$key] = array(
        '#type' => 'textfield',
        '#title' => $dimension['name'],
        '#default_value' => $value[$key],
        '#size' => 15,
        '#maxlength' => 16,
        '#required' => $instance['required'] && $delta == 0,
        '#field_suffix' => '&times;',
        '#prefix' => '<div class="physical-dimension-form-item">',
        '#suffix' => '</div>',
      );
    }

    // Remove the suffix from the last dimension element.
    unset($element[$key]['#field_suffix']);

    // If the user cannot select a different unit of measurement and the current
    // unit is the same as the default...
    if (empty($settings['unit_select_list']) && $value['unit'] == $settings['default_unit']) {

      // Display the unit of measurement after the last textfield using the
      // final $key value from the above foreach loop.
      $element[$key]['#field_suffix'] = physical_dimension_unit_abbreviation($value['unit']);

      // Add a hidden value for the default unit of measurement.
      $element['unit'] = array(
        '#type' => 'value',
        '#value' => $value['unit'],
      );
    }
    else {

      // Get an options list of dimension units of measurement.
      $options = physical_dimension_unit_options(FALSE);

      // If the user isn't supposed to have access to select a unit of
      // measurement, only allow the default and the current unit.
      if (empty($settings['unit_select_list'])) {
        $options = array_intersect_key($options, drupal_map_assoc(array(
          $value['unit'],
          $settings['default_unit'],
        )));
      }

      // Display a unit of measurement select list after the textfield.
      $element['unit'] = array(
        '#type' => 'select',
        '#options' => $options,
        '#default_value' => $value['unit'],
        '#prefix' => '<div class="physical-dimensions-unit-form-item">',
        '#suffix' => '</div>',
      );
    }
    return $element;
  }
}