Note: Requires content.module.'); } } /** * Implementation of hook_widget_info(). */ function options_widget_info() { return array( 'options_select' => array( 'label' => 'Select List', 'field types' => array('text', 'number_integer'), ), 'options_radios' => array( 'label' => 'Radio Boxes', 'field types' => array('text', 'number_integer'), ), 'options_checkbox' => array( 'label' => 'Checkboxes', 'field types' => array('text', 'number_integer'), ), ); } /** * Implementation of hook_widget_settings(). */ function options_widget_settings($op, $widget) { switch ($op) { case 'form': $form['view'] = array( '#type' => 'fieldset', '#title' => t('View Format'), '#description' => t('Formatting options for views of this field.'), ); $form['view']['options_view_multiple'] = array( '#type' => 'select', '#title' => t('Multiple values'), '#default_value' => $field['widget']['options_view_multiple'] ? $field['widget']['options_view_multiple'] : 'comma', '#options' => options_view_multiple(), ); $form['view']['options_view_value'] = array( '#type' => 'select', '#title' => t('Label and value'), '#default_value' => $field['widget']['options_view_value'] ? $field['widget']['options_view_value'] : 'div', '#options' => options_view_value(), ); $form['view']['options_view_wrapper'] = array( '#type' => 'select', '#title' => t('Wrapper'), '#default_value' => $field['widget']['options_view_wrapper'] ? $field['widget']['options_view_wrapper'] : 'div', '#options' => options_view_wrapper(), ); return $form; case 'validate': break; case 'save': return array('options_view_multiple', 'options_view_value', 'options_view_wrapper'); break; } } /** * Implementation of hook_widget(). */ function options_widget($op, &$node, $field) { switch ($op) { case 'form': $node_field = $node->$field['field_name']; $type = str_replace('options_','',$field['widget']['type']); $options = ($field['required'] or $type == 'checkbox' or $type == 'radio') ? options_options($field) : options_none($field) + options_options($field); $current_vals = array(); if ($field['multiple'] and is_array($node_field)) { foreach ($node_field as $delta => $val) { $current_vals[] = $val['value']; } } else { $current_vals[] = $node_field['value']; } $form[$field['field_name']] = array( '#tree' => TRUE, ); if ($type == 'select') { $form[$field['field_name']]['value'] = array( '#type' => 'select', '#title' => t($field['widget']['label']), '#default_value' => $current_vals ? $current_vals : options_blank_value($field['type']), '#required' => $field['required'], '#multiple' => $field['multiple'], '#options' => $options, '#description' => $field['widget']['description'], ); } elseif ($type == 'checkbox') { $form[$field['field_name']]['prefix'] = array( '#type' => 'markup', '#value' => theme('form_element', t($field['widget']['label']), ''), ); foreach ($options as $key => $val) { $form[$field['field_name']][]['value'] = array( '#type' => 'checkbox', '#title' => $val, '#default_value' => in_array($key, $current_vals) ? $key : options_blank_value($field['type']), '#required' => $field['required'], '#return_value' => $key, ); } $form[$field['field_name']]['suffix'] = array( '#type' => 'markup', '#value' => '
'. $field['widget']['description'] . '
', ); } elseif ($type == 'radios') { $form[$field['field_name']]['value'] = array( '#type' => 'radios', '#title' => t($field['widget']['label']), '#default_value' => $current_vals[0] ? $current_vals[0] : options_blank_value($field['type']), '#required' => $field['required'], '#multiple' => $field['multiple'], '#options' => $options, '#description' => $field['widget']['description'], ); } return $form; break; case 'validate': return; break; case 'submit': return; case 'view': return; } } /** * Implementation of hook_field_settings(). */ function options_field_settings($op, $field, $form = array()) { switch ($op) { case ('form'): theme_add_style(drupal_get_path('module', 'options') .'/options.css'); switch($field['widget']['type']) { case ('text'): // store options values in hidden fields if widget is currently set to text field // this will keep values from being lost if admin switches to a text field and then back again // added to reduce confusion for non-programmer users who may not understand implications of making switch // and to eliminate the need to display options values if an options widget is not being used $form['options_none'] = array('#type' => 'hidden', '#value' => $field['options_none']); $form['options_none'] = array('#type' => 'hidden', '#value' => $field['options_list']); $form['options_none'] = array('#type' => 'hidden', '#value' => $field['options_choice']); $form['options_none'] = array('#type' => 'hidden', '#value' => $field['options_min']); $form['options_none'] = array('#type' => 'hidden', '#value' => $field['options_max']); $form['options_none'] = array('#type' => 'hidden', '#value' => $field['options_increment']); break; default: // store text values as hidden fields if the options widget is being used foreach ($form as $key => $val) { $form[$key] = array('#type' => 'hidden', '#value' => $val['#default_value']); } switch($field['type']) { case('text') : $more = t("The value is the text to actually be stored in the database, the label is displayed to users the option. "); break; default: $more = t("Values must be numbers, labels are what users will see as options. "); break; } $form['options_none'] = array( '#type' => 'textfield', '#title' => t('Label when empty'), '#default_value' => $field['options_none'], '#description'=> t('Label to be used in input form when field has a empty value. Displayed as an option in select list and radio widgets when the field is not required. A blank label is allowable. '), ); $form['options'] = array( '#type' => 'markup', '#value' => theme('form_element', t('Options'), ''), ); $form['options_list'] = array( '#type' => 'fieldset', '#title' => t('List'), ); $form['options_list']['options_choice'] = array( '#type' => 'radio', '#default_value' => is_numeric($field['options_choice']) ? $field['options_choice'] : 0, '#return_value' => 0, '#title' => t('Generate options from a list of values and labels.'), ); $form['options_list']['options_list'] = array( '#type' => 'textarea', '#title' => t('List'), '#default_value' => $field['options_list'] ? $field['options_list'] : '', '#description' => t("Put each option on a separate line, using the format value|label. ") . $more, ); if ($field['type'] == 'number_integer') { $form['options_range'] = array( '#type' => 'fieldset', '#title' => t('Number Range'), ); $form['options_range']['options_choice'] = array( '#type' => 'radio', '#default_value' => is_numeric($field['options_choice']) ? $field['options_choice'] : 0, '#return_value' => 1, '#title' => t('Generate options as a range of numbers.'), ); $form['options_range']['options_min'] = array( '#prefix' => '
', '#type' => 'textfield', '#title' => t('Minimum'), '#default_value' => is_numeric($field['options_min']) ? $field['options_min'] : 1, '#size' => 10, ); $form['options_range']['options_max'] = array( '#type' => 'textfield', '#title' => t('Maximum'), '#default_value' => is_numeric($field['options_max']) ? $field['options_max'] : 10, '#size' => 10, ); $form['options_range']['options_increment'] = array( '#type' => 'textfield', '#title' => t('Increment'), '#default_value' => is_numeric($field['options_increment']) ? $field['options_increment'] : 1, '#size' => 10, '#suffix' => '
', ); $field['options_choice'] = $form['options_range']['options_choice']['#default_value']; $field['options_min'] = $form['options_range']['options_min']['#default_value']; $field['options_max'] = $form['options_range']['options_max']['#default_value']; $field['options_increment'] = $form['options_range']['options_increment']['#default_value']; } $form['options_list']['old_options_list'] = array( '#type' => 'hidden', '#value' => serialize(options_options($field)), ); } return $form; break; case ('save'): return array('options_none', 'options_list', 'old_options_list', 'options_choice', 'options_min', 'options_max', 'options_increment'); break; case ('validate'): $options = options_options($field); $keys = array_keys($options); $options_old = unserialize($field['old_options_list']); $keys_old = array_keys($options_old); foreach ($keys as $key) { if ($field['type'] != 'text') { if (!is_numeric($key)) form_set_error('options_list',t("Values must be numbers.")); break; } } // check for duplicate keys if (sizeof($keys) <> sizeof($options)) form_set_error('options_list',t("Duplicate values are not allowed.")); // check for blank or zero keys $invalid = array('', ' ', 0); if (array_intersect($keys, $invalid)) form_set_error('options_list',t("Values cannot be blank or zero since empty values need special handling.")); // if options list has changed, check whether the deleted values are in use if (sizeof(array_intersect($options, $options_old)) != sizeof($options)) { $not_changed = array_intersect($keys, $keys_old); if (sizeof($not_changed) <> sizeof($keys_old)) { $in_use = array(); foreach ($keys_old as $key => $val) { if (!in_array($val, $not_changed)) { $table = 'node_data_'.$field['field_name']; $table_field = $widget['field_name'] . '_value'; $qrytext = "SELECT nid FROM {$table} WHERE $table_field='$val'"; $arr = db_fetch_array(db_query($qrytext)); if ($arr['nid'] > 0) $in_use[] = $val; } } if (sizeof($in_use) > 0) { foreach ($in_use as $item) { form_set_error('options_list', t("You tried to remove '%s' from the option list, but it is still in use in the database and cannot be removed.", array('%s' => $item))); } } } } } } /** * Implementation of hook_field(). */ function options_field($op, $node, &$field, $a2, $a3, $a4) { switch ($op) { case 'load': return; case 'view': $node_field = $node->$field['field_name']; $node_field['view'] = options_field_view($node, $field); $node->$field['field_name'] = $node_field; $output = theme('options_view_multiple', $node_field['view'], $field['widget']['options_view_multiple']); $output = theme('options_view_value', $field['widget']['label'], $output, $field['field_name'], $field['widget']['options_view_types']); return theme('options_view_wrapper', $field['field_name'], $output, $field['field_name'], $field['widget']['options_view_wrapper']); case 'insert': case 'update': return; case 'delete': return; } } /** * Implementation of hook_field_view() which performs any translation necessary. */ function options_field_view(&$node, $field) { (array)$node->$field['field_name']; $options = options_none($field) + options_options($field); foreach ($node->$field['field_name'] as $item) { foreach ((array)$item as $val) { if ($val > '0') $list[] = $options[$val]; } } return ($list); } /* * function to create an array of available options for this field */ function options_options($field) { $options = array(); switch ($field['options_choice']) { case (1): // create a numeric range using settings parameters for ($i = intval($field['options_min']); $i <= intval($field['options_max']); $i += intval($field['options_increment'])) { $options[$i] = $i; } return $options; break; default: // create an option list from settings textarea $vals = explode("\n",trim($field['options_list'])); foreach ($vals as $item) { $val = explode('|',$item); $options[trim($val[0])] = trim($val[1]); } return $options; } } /* * function to create field and label for an empty value */ function options_none($field) { return array(options_blank_value($field['type']) => $field['options_none']); } /* * function to set the database value for a blank field */ function options_blank_value($field_type = 'text') { switch ($field_type) { case ('text'): return ''; default: return 0; } } /* * function to create an array of possible formats for viewing multiple values */ function options_view_multiple() { return array( 'comma' => t('One line, separated by commas'), 'space' => t('One line, separated by spaces'), 'newline' => t('Each on new line'), 'list' => t('Bulleted list'), ); } /* * theme for the above function */ function theme_options_view_multiple($list, $type) { if (!is_array($list)) $list = array($list); switch ($type) { case ('newline'): $output = implode('
', $list); break; case ('list'): $output = theme('item_list', $list); break; case ('space'): $output = implode(' ',$list); break; default: $output = implode(', ',$list); } return $output; } /* * function to create a formatting types for the label and data */ function options_view_value() { return array( 'div' => t('As label and div'), 'dl' => t('As dt and dd'), 'td' => t('As table row'), 'plain' => t('Plain, no formatting, no label'), ); } /* * theme for the above function */ function theme_options_view_value($label, $data, $field_name, $view_type = 'dl') { switch ($view_type) { case ('dl'): return '
'.$label.':
'.$data.'
'; break; case ('div'): return '
'.$data.'
'; break; case ('td'): return ''.$label.':'.$data.''; break; default: return $data; } } /* * function to create a wrappers for the field */ function options_view_wrapper() { return array( 'fieldset' => t('Wrap in fieldset'), 'div' => t('Wrap in div'), 'dl' => t('Wrap with dl'), 'table' => t('Wrap in table'), 'plain' => t('Plain, no wrapper'), ); } /* * theme for the above function */ function theme_options_view_wrapper($title, $data, $field_name, $wrapper_type = 'dl') { switch ($wrapper_type) { case ('fieldset'): return '
'.$title.''.$data.'
'; break; case ('div'): return '
'.$data.'
'; break; case ('dl'): return '
'.$data.'
'; break; case ('table'): return ''.$data.'
'; break; default: return $data; } }