You are here

function multiselect_field_widget_form in Multiselect 7

Implements hook_field_widget_form(). Build the form widget using Form API (as much as possible).

File

./multiselect.module, line 99
Allows users to select multiple items in an easier way than the normal node-reference widget.

Code

function multiselect_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {

  /* START copy from options.module */

  // Abstract over the actual field columns, to allow different field types to
  // reuse those widgets.
  $value_key = key($field['columns']);
  $type = str_replace('options_', '', $instance['widget']['type']);

  //$multiple = $field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED;
  $multiple = $field['cardinality'];
  $required = $element['#required'];
  $has_value = isset($items[0][$value_key]);
  $properties = _options_properties($type, $multiple, $required, $has_value);

  // Prepare the list of options.
  $options = _options_get_options($field, $instance, $properties, NULL, NULL);

  // Remove all tags from values. Very useful for views displays.
  $options = array_map("strip_tags", $options);

  // Put current field values in shape.
  $default_value = _options_storage_to_form($items, $options, $value_key, $properties);

  /* END copy from options.module */
  $widget = _multiselect_build_widget_code($options, $items, $element, $required);

  //for each selected item ($items are in delta order still), we unset the item from $options (which is in nid/tid order)

  //then just re-append it to the bottom of the options array, in order of $items, this fools the FAPI and retains order on edit
  foreach ($items as $item) {
    if (isset($options[$item[$value_key]])) {
      $val = $options[$item[$value_key]];
      unset($options[$item[$value_key]]);
      $options[$item[$value_key]] = $val;
    }
  }

  // Build the basic select box using Form API.
  $element += array(
    '#type' => 'select',
    '#title' => $element['#title'],
    '#description' => $element['#description'],
    '#required' => $required,
    '#multiple' => $multiple,
    '#options' => $options,
    //'#options' => $selected_options,
    '#size' => 10,
    '#prefix' => $widget['prefix_pre'] . $widget['prefix_options'] . $widget['prefix_post'],
    '#suffix' => "\n</div>\n",
    '#attributes' => array(
      'class' => array(
        $widget['selfield'],
        'multiselect_sel',
      ),
      'id' => array(
        $element['#field_name'],
      ),
    ),
    '#default_value' => $default_value,
    '#value_key' => $value_key,
    '#element_validate' => array(
      'options_field_widget_validate',
    ),
    '#properties' => $properties,
    '#after_build' => array(
      '_multiselect_after_build',
    ),
  );

  // Attach CSS and Javascript for this widget.
  $module_path = drupal_get_path('module', 'multiselect');
  $element['#attached'] = array(
    'css' => array(
      $module_path . '/multiselect.css',
    ),
    'js' => array(
      $module_path . '/multiselect.js',
    ),
  );
  return $element;
}