function mvf_field_formatter_settings_form in Measured Value Field 7
Implements hook_field_formatter_settings_form().
File
- ./
mvf.module, line 712 - Define a field type of measured value.
Code
function mvf_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$element = array();
// We are able to do configurable formatters in 2 steps. In the 1st step
// user chooses sub formatters and in the 2nd step user defines any settings
// for the chosen sub formatters.
$info = _field_info_collate_types();
$superior_formatter = $instance['display'][$view_mode];
foreach ($field['settings']['meta_info'] as $subfield => $meta_info) {
switch ($superior_formatter['type']) {
case 'mvf_formatter_default':
// Default formatter implies delegating formatting to both sub
// formatters, as to value subformatter, as to unit subformatter.
$is_delegating_unit = TRUE;
break;
case 'mvf_formatter_symbol':
// Symbol formatter already knows how to render the unit part - it
// should be rendered as symbol, so only the value part should be
// delegated to a sub formatter.
$is_delegating_unit = FALSE;
break;
default:
// We are not supposed to be here, let's fallback on delegation.
$is_delegating_unit = TRUE;
break;
}
if ($subfield == 'unit' && !$is_delegating_unit) {
// We do not want to show the sub formatter options for unit.
}
else {
// Looking for formatters that support our sub field type.
$formatters = array();
foreach ($info['formatter types'] as $formatter_type => $formatter) {
if (in_array($meta_info['field_type'], $formatter['field types'])) {
$formatters[$formatter_type] = $formatter;
}
}
$fieldset_id = 'mvf-formatter-' . $subfield;
$element[$subfield] = array(
'#type' => 'fieldset',
'#title' => $meta_info['label'],
'#collapsible' => TRUE,
'#prefix' => '<div id="' . $fieldset_id . '">',
'#suffix' => '</div>',
);
$options = array();
foreach ($formatters as $formatter_type => $formatter) {
$options[$formatter_type] = $formatter['label'];
}
// Since we update values via #ajax, the chosen value in
// $superior_formatter can be overriden in $form_state by the current
// unsaved (yet) value.
if (isset($form_state['values']['fields'][$field['field_name']]['settings_edit_form']['settings'][$subfield]['formatter'])) {
$formatter = $form_state['values']['fields'][$field['field_name']]['settings_edit_form']['settings'][$subfield]['formatter'];
}
elseif (isset($superior_formatter['settings'][$subfield]['formatter'])) {
// Then we check superior formatter to see if there are any stored
// settings there.
$formatter = $superior_formatter['settings'][$subfield]['formatter'];
}
else {
// If we end up here, it's the 1st time formatter settings form is opened,
// since there is no stored settings in superior formatter. So lastly we
// fallback on sub field default formatter.
$formatter = $meta_info['formatter'];
}
// After we have let current $form_state values to override currently
// saved formatter for the subfield, we are now able to mock $field and
// $instance so that in the mocked results the overriden formatter will be
// reflected.
$instance['display'][$view_mode]['settings'][$subfield]['formatter'] = $formatter;
$mocked_field = mvf_field_mockup($field, $subfield);
$mocked_instance = mvf_instance_mockup($field, $instance, $subfield);
$element[$subfield]['formatter'] = array(
'#type' => 'select',
'#title' => t('Formatter'),
'#required' => TRUE,
'#description' => t('Please, choose formatter for the sub field.'),
'#options' => $options,
'#default_value' => $formatter,
'#ajax' => array(
'path' => 'mvf/ajax/formatter/' . $instance['entity_type'] . '/' . $instance['bundle'] . '/' . $field['field_name'] . '/' . $subfield,
'wrapper' => $fieldset_id,
'event' => 'change',
'effect' => 'fade',
),
);
if (isset($formatters[$formatter])) {
$formatter = $formatters[$formatter];
// Since the sub formatter has been chosen, now we can check whether
// the module that defines sub formatter desires to define some settings
// for its sub formatter too.
$function = $formatter['module'] . '_field_formatter_settings_form';
$extra = NULL;
if (function_exists($function)) {
$extra = $function($mocked_field, $mocked_instance, $view_mode, $form, $form_state);
}
if (is_array($extra)) {
// Doing any customizations after collecting data from the module that
// defines a sub formatter.
switch ($subfield) {
case 'value':
if ($field['settings']['meta_info'][$subfield]['field_type'] == 'number_integer') {
// For integer we have to define 'scale' and 'decimal_separator'
// because number module keeps these 2 parameters behind the
// scenes for integer (since they don't make sense to integer)
// in order to use the same formatter for all numbers.
$extra['scale'] = array(
'#type' => 'value',
'#value' => $formatter['settings']['scale'],
);
$extra['decimal_separator'] = array(
'#type' => 'value',
'#value' => $formatter['settings']['decimal_separator'],
);
}
break;
}
$element[$subfield] += $extra;
}
}
}
}
$element['mvf'] = array(
'#type' => 'fieldset',
'#title' => t('Unit output'),
'#collapsible' => TRUE,
);
$element['mvf']['override'] = array(
'#type' => 'checkbox',
'#title' => t('Override instance default unit suggestion?'),
'#default_value' => isset($superior_formatter['settings']['mvf']['override']) ? $superior_formatter['settings']['mvf']['override'] : FALSE,
'#attributes' => array(
'class' => array(
'mvf-formatter-settings-unit-suggestion-override',
),
),
);
$element['mvf']['unit_suggesters_settings'] = array(
'#type' => 'mvf_unit_suggester',
'#title' => t('Unit suggestion'),
'#field' => $field,
'#instance' => $instance,
'#view_mode' => $view_mode,
'#states' => array(
'visible' => array(
':input.mvf-formatter-settings-unit-suggestion-override' => array(
'checked' => TRUE,
),
),
),
);
return $element;
}