You are here

function properties_field_widget_form in Dynamic properties 7

Implements hook_field_widget_form().

File

./properties.module, line 359
This module provides a dynamic property field that can contain an unlimited number of attribute value pairs.

Code

function properties_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $elements = array();
  $field_name = $field['field_name'];
  $values = isset($form_state['values'][$field_name][$langcode]['listing']) ? $form_state['values'][$field_name][$langcode]['listing'] : array();
  drupal_add_css(drupal_get_path('module', 'properties') . '/properties.css');
  drupal_add_js(drupal_get_path('module', 'properties') . '/properties.js');
  $categories =& $form_state[$field_name]['categories'];
  if (!isset($form_state[$field_name]['categories'])) {
    $categories = array();

    // Set up initial content.
    foreach ($items as $item) {

      // First, load the category if necessary.
      if (empty($categories[$item['category']])) {
        $category = properties_category_load($item['category']);
        if (!empty($category)) {
          $categories[$category->name] = array(
            '_weight' => count($form_state[$field_name]['categories']),
            'category' => $category,
            'properties' => array(),
          );
        }
        else {

          // If the category was deleted, ignore it and everything within it.
          continue;
        }
      }
      $attribute = properties_attribute_load($item['attribute']);
      if (!empty($attribute)) {
        $form_state[$field_name]['categories'][$item['category']]['properties'][$attribute->name] = array(
          'attribute' => $attribute->name,
          'category' => $item['category'],
          'value' => $item['value'],
          '_weight' => count($form_state[$field_name]['categories'][$item['category']]['properties']),
        );
      }
    }
  }
  $category_list = array();
  foreach ($categories as $category_name => $item) {
    $category_list[$item['category']->name] = $item['category']->label;

    // Update weight from values.
    if (isset($values[$category_name])) {
      $item['_weight'] = $values[$category_name]['_weight'];
    }

    // Move attributes to new category.
    foreach ($item['properties'] as $delta => $property) {
      if (isset($values[$category_name]['properties'][$property['attribute']])) {
        $property['_weight'] = $values[$category_name]['properties'][$property['attribute']]['_weight'];
        $property['category'] = $values[$category_name]['properties'][$property['attribute']]['category'];
      }
      if ($property['category'] != $category_name) {
        $categories[$property['category']]['properties'][$property['attribute']] = $property;
        unset($categories[$category_name]['properties'][$property['attribute']]);
      }
    }
    usort($item['properties'], '_field_sort_items_helper');
  }
  uasort($categories, '_field_sort_items_helper');
  $id = 'properties-' . drupal_html_id($field_name) . '-wrapper';
  $elements['listing'] = array();
  $tabindex = 1;
  foreach ($categories as $category_name => $category) {
    $elements['listing'][$category_name]['#label'] = $category['category']->label;

    // Only used to trick tabledrag.js.
    $elements['listing'][$category_name]['category'] = array(
      '#type' => 'hidden',
      '#value' => '',
    );
    $elements['listing'][$category_name]['name'] = array(
      '#type' => 'hidden',
      '#value' => $category['category']->name,
    );
    $elements['listing'][$category_name]['_weight'] = array(
      '#type' => 'weight',
      '#title' => t('Weight for category @category', array(
        '@category' => $category['category']->label,
      )),
      '#title_display' => 'invisible',
      '#default_value' => $category['_weight'],
      '#access' => user_access('add properties categories'),
      '#weight' => 100,
    );
    $elements['listing'][$category_name]['delete'] = array(
      '#type' => 'submit',
      '#value' => t('Delete'),
      '#submit' => array(
        'properties_widget_remove_category',
      ),
      '#limit_validation_errors' => array(
        array(
          $field_name,
          $langcode,
        ),
      ),
      '#access' => user_access('add properties categories'),
      '#name' => $category_name,
      '#ajax' => array(
        'callback' => 'properties_widget_update_js',
        'wrapper' => $id,
        'effect' => 'fade',
      ),
    );
    foreach ($category['properties'] as $delta => $property) {
      $element = array();
      $element['category'] = array(
        '#type' => user_access('add properties attributes') ? 'select' : 'hidden',
        '#default_value' => $property['category'],
        '#options' => $category_list,
      );
      $element['attribute'] = array(
        '#type' => 'textfield',
        '#default_value' => $property['attribute'],
        '#autocomplete_path' => 'properties_autocomplete/attribute',
        '#maxlength' => 255,
        '#size' => 32,
        '#access' => user_access('add properties attributes'),
        '#ajax' => array(
          'callback' => 'properties_admin_update_label_js',
          'wrapper' => 'attributes-wrapper',
          'effect' => 'fade',
        ),
      );
      $element['label'] = array(
        '#markup' => !empty($property['attribute']) ? check_plain(properties_attribute_load($property['attribute'])->label) : '',
      );
      $element['value'] = array(
        '#type' => 'textfield',
        '#default_value' => $property['value'],
        '#maxlength' => 255,
        '#size' => 32,
        '#attributes' => array(
          'tabindex' => $tabindex,
          'class' => array(
            'properties-value',
          ),
        ),
      );
      $element['_weight'] = array(
        '#type' => 'weight',
        '#title' => t('Weight for property @property', array(
          '@property' => $element['label']['#markup'],
        )),
        '#title_display' => 'invisible',
        '#default_value' => $property['_weight'],
        '#weight' => 100,
        '#access' => user_access('add properties attributes'),
      );
      $element['delete'] = array(
        '#type' => 'submit',
        '#value' => t('Delete'),
        '#submit' => array(
          'properties_widget_remove_attribute',
        ),
        '#access' => user_access('add properties attributes'),
        '#name' => $property['attribute'],
        '#limit_validation_errors' => array(
          array(
            $field_name,
            $langcode,
          ),
        ),
        '#ajax' => array(
          'callback' => 'properties_widget_update_js',
          'wrapper' => $id,
          'effect' => 'fade',
        ),
      );
      $elements['listing'][$category_name]['properties'][$property['attribute']] = $element;
      $tabindex++;
    }
  }
  $elements += array(
    '#properties_table_id' => $id,
    '#type' => 'fieldset',
    '#theme' => 'properties_properties_form',
    '#title' => t('Properties'),
    '#description' => t('Add properties to this content. Start by adding categories to it.'),
    '#prefix' => '<div id="' . $id . '">',
    '#suffix' => '</div>',
    '#max_delta' => $delta,
    // Container for action form elements, might be empty.
    'actions' => array(),
  );
  if (user_access('add properties categories')) {
    $elements['actions']['new_category'] = array(
      '#type' => 'textfield',
      '#default_value' => '',
      '#autocomplete_path' => 'properties_autocomplete/category',
      '#maxlength' => 255,
      '#size' => 32,
    );
    $elements['actions']['add_category'] = array(
      '#name' => $field_name . $langcode,
      '#type' => 'submit',
      '#value' => t('Add category'),
      '#limit_validation_errors' => array(
        array(
          $field_name,
          $langcode,
        ),
      ),
      '#submit' => array(
        'properties_widget_add_category_submit',
      ),
      '#ajax' => array(
        'callback' => 'properties_widget_update_js',
        'wrapper' => $id,
        'effect' => 'fade',
      ),
    );
  }
  if (!empty($category_list) && user_access('add properties attributes')) {
    $elements['actions']['attribute_category'] = array(
      '#type' => 'select',
      '#options' => $category_list,
    );
    $elements['actions']['new_attribute'] = array(
      '#type' => 'textfield',
      '#default_value' => '',
      '#autocomplete_path' => 'properties_autocomplete/attribute',
      '#maxlength' => 255,
      '#size' => 32,
    );
    $elements['actions']['add_attribute'] = array(
      '#name' => $field_name . $langcode,
      '#type' => 'submit',
      '#value' => t('Add attribute'),
      '#limit_validation_errors' => array(
        array(
          $field_name,
          $langcode,
        ),
      ),
      '#submit' => array(
        'properties_widget_add_attribute_submit',
      ),
      '#ajax' => array(
        'callback' => 'properties_widget_update_js',
        'wrapper' => $id,
        'effect' => 'fade',
      ),
    );
  }
  return $elements;
}