Customized select form options

This is how you can override the select form options by hook_select and add your own theme function. In my case I wanted to add different classes to each option. Based on a vocabulary I create an array with options formatted with 'data' and 'class' tags instead of the normal plain value:

The options array

<?php

//Normal options array
$options = array(1 => "Option one",
        
2 => "Option two");

//Customized options array
$options = array(1 => array("data" => "Option one", "class" => "class-one"),
        
2 => array("data" => "Option two", "class" => "class-two"));
?>

The select form array

<?php
//Add a flag '#zimonitor_select' telling your overriding hook_select function to act different
 
$form['ticket']['bj_status'] = array(
   
'#title' => t('Backup status'),
   
'#type' => 'select',
   
'#options' => _get_backupjob_status_options(TRUE),
   
'#weight' => 1,
   
'#zimonitor_select' => TRUE,
  );
?>

The hook_select and your customized options function

<?php
/**
 * Hook Select
 * to be able to call customized theming of options
 *
 * @param unknown_type $element
 * @return unknown
 */
function phptemplate_select($element) {

     
$select = '';
     
$size = $element['#size'] ? ' size="' . $element['#size'] . '"' : '';
     
_form_set_class($element, array('form-select'));
     
$multiple = $element['#multiple'];
     
         
//Here you make the decision to choose your theme function or the original one based on the flag you added in the form ('#zimonitor_select')
     
if ($element['#zimonitor_select'] == TRUE) {
          return
theme('form_element', $element, '<select name="' . $element['#name'] . '' . ($multiple ? '[]' : '') . '"' . ($multiple ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) . ' id="' . $element['#id'] . '" ' . $size . '>' . zimonitor_form_select_options($element) . '</select>');
      }else{
          return
theme('form_element', $element, '<select name="' . $element['#name'] . '' . ($multiple ? '[]' : '') . '"' . ($multiple ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) . ' id="' . $element['#id'] . '" ' . $size . '>' . form_select_options($element) . '</select>');
      }
}


/**
 * Zimonitor class theming of select form options
 *
 * @param unknown_type $element
 * @param unknown_type $choices
 * @return unknown
 */
function zimonitor_form_select_options($element, $choices = NULL) {

   
  if (!isset(
$choices)) {
   
$choices = $element['#options'];
  }

 
// array_key_exists() accommodates the rare event where $element['#value'] is NULL.
  // isset() fails in this situation.
 
$value_valid = isset($element['#value']) || array_key_exists('#value', $element);
 
$value_is_array = $value_valid && is_array($element['#value']);
 
$options = '';
  foreach (
$choices as $key => $choice) {
    if (
is_array($choice['data'])) {
     
$options .= '<optgroup label="' . $key . '">';
     
$options .= zimonitor_form_select_options($element, $choice['data']);
     
$options .= '</optgroup>';
    }
    elseif (
is_object($choice)) {
     
$options .= zimonitor_form_select_options($element, $choice->option);
    }
    else {
     
$key = (string) $key;
      if (
$value_valid && (!$value_is_array && (string) $element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
       
$selected = ' selected="selected"';
      }
      else {
       
$selected = '';
      }
     
$options .= '<option class="' . check_plain($choice['class']) . '"  value="' . check_plain($key) . '"' . $selected . '>' . check_plain($choice['data']) . '</option>';
    }
  }
  return
$options;
}
?>
Knowledge keywords: