cck_select_other.module in CCK Select Other 6
Same filename and directory in other branches
Implements a select list widget that lets a user provide an alternate option.
File
cck_select_other.moduleView source
<?php
/**
* @file
* Implements a select list widget that lets a user provide an alternate option.
*/
/**
* Implementation of hook_widget_info().
*/
function cck_select_other_widget_info() {
return array(
'cck_select_other' => array(
'label' => t('Select other list'),
'field types' => array(
'text',
'number_integer',
'number_decimal',
'number_float',
),
'multiple values' => CONTENT_HANDLE_MODULE,
'callbacks' => array(
'default value' => CONTENT_CALLBACK_DEFAULT,
),
),
);
}
/**
* Implementation of hook_widget_settings
*/
function cck_select_other_widget_settings($op, $widget) {
switch ($op) {
case 'form':
$form['select_list_options'] = array(
'#type' => 'textarea',
'#title' => t('Select list options'),
'#description' => t('CCK Select Other uses a separate text area to generate options. You may also put restricted values in the Allowed Values text area.'),
'#default_value' => $widget['select_list_options'],
);
$form['select_list_options_fieldset']['advanced_options'] = array(
'#type' => 'fieldset',
'#title' => t('PHP code'),
'#collapsible' => TRUE,
'#collapsed' => empty($widget['select_list_options_php']),
);
if (user_access('Use PHP input for field settings (dangerous - grant with care)')) {
$form['select_list_options_fieldset']['advanced_options']['select_list_options_php'] = array(
'#type' => 'textarea',
'#title' => t('Code'),
'#default_value' => !empty($widget['select_list_options_php']) ? $widget['select_list_options_php'] : '',
'#rows' => 6,
'#description' => t('Advanced usage only: PHP code that returns a keyed array of proposed select list options. Should not include <?php ?> delimiters. If this field is filled out, the array returned by this code will override the proposed select list options above.'),
);
}
else {
$form['select_list_options_fieldset']['advanced_options']['markup_select_list_options_php'] = array(
'#type' => 'item',
'#title' => t('Code'),
'#value' => !empty($widget['select_list_options_php']) ? '<code>' . check_plain($widget['select_list_options_php']) . '</code>' : t('<none>'),
'#description' => empty($widget['select_list_options_php']) ? t("You're not allowed to input PHP code.") : t('This PHP code was set by an administrator and will override the allowed values list above.'),
);
}
return $form;
break;
case 'save':
return array(
'select_list_options',
'select_list_options_php',
);
break;
}
}
/**
* Implementation of hook_elements
*/
function cck_select_other_elements() {
return array(
'cck_select_other' => array(
'#input' => TRUE,
'#columns' => array(
'value',
),
'#delta' => 0,
'#process' => array(
'cck_select_other_process',
),
'#pre_render' => array(
'cck_select_other_pre_render',
),
'#post_render' => array(
'cck_select_other_post_render',
),
),
);
}
/**
* Implementation of hook_widget().
*/
function cck_select_other_widget(&$form, &$form_state, $field, $items, $delta = NULL) {
$element = array(
'#type' => $field['widget']['type'],
'#default_value' => '',
);
$options = cck_select_other_options($field);
if (empty($items)) {
$items[] = array(
'value' => '',
);
}
if (!isset($options[$items[$delta]['value']])) {
$def = 'other';
}
else {
$def = $items[$delta]['value'];
}
$element['select_other_list'] = array(
'#type' => 'select',
'#title' => t(''),
'#description' => t('Select other to enter your own option.'),
'#options' => $options,
'#default_value' => $def,
);
$element['select_other_text_input'] = array(
'#type' => 'textfield',
'#title' => t('Specify other'),
'#default_value' => $def == 'other' ? check_plain($items[$delta]['value']) : '',
);
return $element;
}
/**
* Process an individual element.
*
* Build the form element. When creating a form using FAPI #process,
* note that $element['#value'] is already set.
*
* The $fields array is in $form['#field_info'][$element['#field_name']].
*/
function cck_select_other_process($element, $edit, &$form_state, $form) {
$field_name = $element['#field_name'];
$field = $form['#field_info'][$field_name];
$delta = $element['#delta'];
$field_key = $element['#columns'][0];
$element['#type'] = 'fieldset';
unset($element['#value']);
//FIXME: still necessary? See new else block down below...
$element['#collapsible'] = TRUE;
$element['#collapsed'] = FALSE;
if ($edit['select_other_list'] == 'other' && !empty($edit['select_other_text_input']) && !empty($edit)) {
$element['#value'] = array(
array(
'value' => $edit['select_other_text_input'],
),
);
$form_state['values'][$field_name] = $element['#value'][$delta];
$form_state['clicked_button']['#post'][$field_name] = $element['#value'][$delta];
}
elseif (!empty($edit)) {
$element['#value'] = array(
array(
'value' => $edit['select_other_list'],
),
);
$form_state['values'][$field_name] = $element['#value'][$delta];
$form_state['clicked_button']['#post'][$field_name] = $element['#value'][$delta];
}
else {
$element['#value'] = '';
}
if (empty($element['#element_validate'])) {
$element['#element_validate'] = array();
}
$form_state['#field_info'][$field['field_name']] = $field;
if (!empty($edit)) {
unset($element['select_other_list']);
unset($element['select_other_text_input']);
}
return $element;
}
/**
* Helper function for finding the options list for this field.
*/
function cck_select_other_options($field) {
$options = eval($field['widget']['select_list_options_php']);
if (empty($options)) {
$options_str = $field['widget']['select_list_options'];
if (!empty($options_str)) {
$options_arr = preg_split("/[\r]?[\n]/", $options_str);
if (count($options_arr) > 0) {
foreach ($options_arr as $option_str) {
$option_arr = preg_split("/\\|/", $option_str);
if (count($option_arr) == 2) {
$options[check_plain($option_arr[0])] = t('!option', array(
'!option' => $option_arr[1],
));
}
else {
$options[check_plain($option_arr[0])] = t('!option', array(
'!option' => $option_arr[0],
));
}
}
}
}
}
else {
foreach ($options as $key => $option) {
if (!is_numeric($key)) {
$key = check_plain($key);
}
$options[$key] = t('!option', array(
'!option' => $option,
));
}
}
if (!isset($options['other'])) {
$options['other'] = t('Other');
}
return $options;
}
/**
* Pre render callback for the form so we can recreate the fake form after it gets
* blown away by the CCK process callback.
* @param $form the form
* @return $form
*/
function cck_select_other_pre_render($form) {
static $js;
if (isset($form['select_other_list'])) {
return $form;
}
$field_name = substr($form['#field_name'], 6);
if (!$js) {
drupal_add_js(array(
'CCKSelectOther' => array(
'field' => $field_name,
),
), 'setting');
drupal_add_js(drupal_get_path('module', 'cck_select_other') . '/cck_select_other.js');
$js = TRUE;
}
else {
drupal_add_js(array(
'CCKSelectOther' => array(
'field' => $field_name,
),
), 'setting');
}
unset($form['#default_value']);
unset($form['#value']);
$field = content_fields($form['#field_name']);
$def = $form['#post'][$form['#field_name']]['select_other_text_input'];
$select_def = $form['#post'][$form['#field_name']]['select_other_list'];
$delta = $form['#delta'];
$options = cck_select_other_options($field);
$new_form = array(
'#type' => 'fieldset',
'#title' => t($field['widget']['label']),
'#description' => $form['#description'],
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#delta' => $form['#delta'],
'#field_name' => $form['#field_name'],
'#type_name' => $form['#type_name'],
'#tree' => $form['#tree'],
);
$new_form['select_other_list'] = array(
'#id' => 'edit-field-' . $field_name . '-select-other-list',
'#name' => $form['#field_name'] . '[select_other_list]',
'#parents' => array(
'cck_select_other',
),
'#type' => 'select',
'#title' => t(''),
'#description' => t('Select other to enter your own option.'),
'#options' => $options,
'#default_value' => $select_def,
'#value' => $select_def,
'#weight' => -10,
);
$new_form['select_other_text_input'] = array(
'#id' => 'edit-field-' . $field_name . '-select-other-text-input',
'#name' => $form['#field_name'] . '[select_other_text_input]',
'#parents' => array(
'cck_select_other',
),
'#type' => 'textfield',
'#title' => t('Specify other'),
'#default_value' => $select_def == 'other' ? check_plain($def) : '',
'#value' => $select_def == 'other' ? check_plain($def) : '',
);
return $new_form;
}
/**
* Post-render callback to add javascript functionality
* @param $form
* @return $form
*/
function cck_select_other_post_render($content, $elements) {
static $js;
$field_name = substr($elements['#field_name'], 6);
if (!$js) {
drupal_add_js(array(
'CCKSelectOther' => array(
'field' => $field_name,
),
), 'setting');
drupal_add_js(drupal_get_path('module', 'cck_select_other') . '/cck_select_other.js');
$js = TRUE;
}
else {
drupal_add_js(array(
'CCKSelectOther' => array(
'field' => $field_name,
),
), 'setting');
}
return $content;
}
/**
* Implementation of hook_views_api().
*/
function cck_select_other_views_api() {
return array(
'api' => '2',
'path' => drupal_get_path('module', 'cck_select_other') . '/views',
);
}
Functions
Name | Description |
---|---|
cck_select_other_elements | Implementation of hook_elements |
cck_select_other_options | Helper function for finding the options list for this field. |
cck_select_other_post_render | Post-render callback to add javascript functionality |
cck_select_other_pre_render | Pre render callback for the form so we can recreate the fake form after it gets blown away by the CCK process callback. |
cck_select_other_process | Process an individual element. |
cck_select_other_views_api | Implementation of hook_views_api(). |
cck_select_other_widget | Implementation of hook_widget(). |
cck_select_other_widget_info | Implementation of hook_widget_info(). |
cck_select_other_widget_settings | Implementation of hook_widget_settings |