diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-07-17 19:19:39 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-07-17 19:19:39 +0000 |
commit | b135d644fe726e763c0a7f75ba47c4eeab4bfb88 (patch) | |
tree | cd2c1983f291527f6708606eeb8aed9e9bbaefe2 /modules/field_ui | |
parent | ecc7ce08754ca321110c25ca29567f9726813637 (diff) | |
download | brdo-b135d644fe726e763c0a7f75ba47c4eeab4bfb88.tar.gz brdo-b135d644fe726e763c0a7f75ba47c4eeab4bfb88.tar.bz2 |
- Patch #796658 by yched, andypost: UI for field formatter settings.
Diffstat (limited to 'modules/field_ui')
-rw-r--r-- | modules/field_ui/field_ui-display-overview-table.tpl.php | 35 | ||||
-rw-r--r-- | modules/field_ui/field_ui.admin.inc | 210 | ||||
-rw-r--r-- | modules/field_ui/field_ui.api.php | 65 | ||||
-rw-r--r-- | modules/field_ui/field_ui.css | 29 | ||||
-rw-r--r-- | modules/field_ui/field_ui.js | 2 |
5 files changed, 324 insertions, 17 deletions
diff --git a/modules/field_ui/field_ui-display-overview-table.tpl.php b/modules/field_ui/field_ui-display-overview-table.tpl.php index c9c39593e..0fe4e0a1f 100644 --- a/modules/field_ui/field_ui-display-overview-table.tpl.php +++ b/modules/field_ui/field_ui-display-overview-table.tpl.php @@ -16,35 +16,51 @@ */ ?> <?php if ($rows): ?> +<div id="field-display-overview-wrapper"> <table id="field-display-overview" class="field-display-overview sticky-enabled"> <thead> <tr> <th><?php print t('Field'); ?></th> <th><?php print t('Weight'); ?></th> <th><?php print t('Label'); ?></th> - <th><?php print t('Format'); ?></th> + <th colspan="3"><?php print t('Format'); ?></th> </tr> </thead> <tbody> <tr class="region-message region-visible-message <?php print empty($rows['visible']) ? 'region-empty' : 'region-populated'; ?>"> - <td colspan="4"><em><?php print t('No field is displayed'); ?></em></td> + <td colspan="5"><em><?php print t('No field is displayed'); ?></em></td> </tr> <?php $count = 0; foreach ($rows['visible'] as $row): ?> - <tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>"> + <tr id="<?php print $row->id; ?>" class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>"> <td><span class="<?php print $row->label_class; ?>"><?php print $row->human_name; ?></span></td> <td><?php print $row->weight . $row->hidden_name; ?></td> <td><?php if (isset($row->label)) print $row->label; ?></td> - <td><?php print $row->type; ?></td> + <?php if (isset($row->settings_edit_form)) : ?> + <td colspan="3"> + <?php print $row->type; ?> + <?php print $row->settings_edit_form; ?> + </td> + <?php else :?> + <td> + <?php print $row->type; ?> + </td> + <td class="field-formatter-summary-cell"> + <?php print $row->settings_summary; ?> + </td> + <td> + <?php print $row->settings_edit; ?> + </td> + <?php endif; ?> </tr> <?php $count++; endforeach; ?> <tr class="region-title region-title-hidden"> - <td colspan="4"><?php print t('Hidden'); ?></td> + <td colspan="5"><?php print t('Hidden'); ?></td> </tr> <tr class="region-message region-hidden-message <?php print empty($rows['hidden']) ? 'region-empty' : 'region-populated'; ?>"> - <td colspan="4"><em><?php print t('No field is hidden'); ?></em></td> + <td colspan="5"><em><?php print t('No field is hidden'); ?></em></td> </tr> <?php foreach ($rows['hidden'] as $row): ?> <tr class="<?php print $count % 2 == 0 ? 'odd' : 'even'; ?> <?php print $row->class ?>"> @@ -52,9 +68,16 @@ <td><?php print $row->weight . $row->hidden_name; ?></td> <td><?php if (isset($row->label)) print $row->label; ?></td> <td><?php print $row->type; ?></td> + <td class="field-formatter-summary-cell"> + <?php print $row->settings_summary; ?> + </td> + <td> + <?php print $row->settings_edit; ?> + </td> </tr> <?php $count++; endforeach; ?> </tbody> </table> +</div> <?php endif; ?> diff --git a/modules/field_ui/field_ui.admin.inc b/modules/field_ui/field_ui.admin.inc index 5b8383876..3cf095f13 100644 --- a/modules/field_ui/field_ui.admin.inc +++ b/modules/field_ui/field_ui.admin.inc @@ -724,6 +724,10 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund return $form; } + $form_state += array( + 'formatter_settings_edit' => NULL, + ); + $table = array( '#theme' => 'field_ui_display_overview_table', '#field_rows' => array(), @@ -742,7 +746,6 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund foreach ($instances as $name => $instance) { $display = $instance['display'][$view_mode]; - $table[$name]['human_name'] = array( '#markup' => check_plain($instance['label']), ); @@ -762,13 +765,115 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund ); $field = field_info_field($instance['field_name']); + // The handling of the 'hidden' region in field_ui.js relies on the + // 'formatter type' select, so it is present in all cases, and hidden with + // CSS when the row is in 'edit settings' mode. $formatter_options = field_ui_formatter_options($field['type']); $formatter_options['hidden'] = t('<Hidden>'); $table[$name]['type'] = array( '#type' => 'select', '#options' => $formatter_options, '#default_value' => $display['type'], + '#ajax' => array( + 'callback' => 'field_ui_formatter_settings_js', + 'wrapper' => 'field-display-overview-wrapper', + 'effect' => 'fade', + ), + '#field_name' => $name, + '#op' => 'change_type', ); + // Formatter settings. + + // Check the currently selected formatter, and merge persisted values for + // formatter settings. + if (isset($form_state['values']['settings'][$name]['type'])) { + $formatter_type = $form_state['values']['settings'][$name]['type']; + } + else { + $formatter_type = $display['type']; + } + if (isset($form_state['formatter_settings'][$name])) { + $settings = $form_state['formatter_settings'][$name]; + } + else { + $settings = $display['settings']; + } + $settings += field_info_formatter_settings($formatter_type); + + $instance['display'][$view_mode]['type'] = $formatter_type; + $formatter = field_info_formatter_types($formatter_type); + $instance['display'][$view_mode]['module'] = $formatter['module']; + $instance['display'][$view_mode]['settings'] = $settings; + + // Base button element for the various formatter settings actions. + $base_button = array( + '#submit' => array('field_ui_formatter_settings_submit'), + '#ajax' => array( + 'callback' => 'field_ui_formatter_settings_js', + 'wrapper' => 'field-display-overview-wrapper', + 'effect' => 'fade', + ), + '#field_name' => $name, + ); + + if ($form_state['formatter_settings_edit'] == $name) { + // We are currently editing this field's formatter settings. Display the + // settings form and submit buttons. + $table[$name]['settings_edit_form'] = array(); + $additions = module_invoke($formatter['module'], 'field_formatter_settings_form', $field, $instance, $view_mode, $form, $form_state); + if (is_array($additions)) { + $table[$name]['settings_edit_form'] = array( + '#type' => 'container', + '#attributes' => array('class' => array('field-formatter-settings-edit-form')), + ); + $table[$name]['settings_edit_form']['label'] = array( + '#markup' => t('Format settings:') . ' <span class="formatter-name">' . $formatter['label'] . '</span>', + ); + $table[$name]['settings_edit_form']['settings'] = $additions; + $table[$name]['settings_edit_form']['actions'] = array('#type' => 'actions'); + $table[$name]['settings_edit_form']['actions']['save_settings'] = $base_button + array( + '#type' => 'submit', + '#name' => $name . '_formatter_settings_update', + '#value' => t('Update'), + '#op' => 'update', + ); + $table[$name]['settings_edit_form']['actions']['cancel_settings'] = $base_button + array( + '#type' => 'submit', + '#name' => $name . '_formatter_settings_cancel', + '#value' => t('Cancel'), + '#op' => 'cancel', + // Do not check errors for the 'Cancel' button. + '#limit_validation_errors' => array(), + ); + $table[$name]['#settings_editing'] = TRUE; + // When formatter is changed, cancel the currently edited settings. The + // select 'formatter type' input is hidden in editing mode, so this only + // happens is the row is dragged into the 'hidden' section. + $table[$name]['type']['#ajax']['trigger_as'] = array('name' => $name . '_formatter_settings_cancel'); + } + } + else { + // Display a summary of the current formatter settings. + $summary = module_invoke($formatter['module'], 'field_formatter_settings_summary', $field, $instance, $view_mode); + $table[$name]['settings_summary'] = array(); + $table[$name]['settings_edit'] = array(); + if ($summary) { + $table[$name]['settings_summary'] = array( + '#markup' => '<div class="field-formatter-summary">' . $summary . '</div>', + ); + $table[$name]['settings_edit'] = $base_button + array( + '#type' => 'image_button', + '#name' => $name . '_formatter_settings_edit', + '#src' => 'misc/configure.png', + '#attributes' => array('class' => array('field-formatter-settings-edit'), 'alt' => t('Edit')), + '#op' => 'edit', + // Do not check errors for the 'Edit' button. + '#limit_validation_errors' => array(), + '#prefix' => '<div class="field-formatter-settings-edit-wrapper">', + '#suffix' => '</div>', + ); + } + } $table['#field_rows'][] = $name; // Collect default formatters for the JS script. @@ -796,8 +901,11 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund '#options' => $extra_visibility_options, '#default_value' => $display['visible'] ? 'visible' : 'hidden', ); + $table[$name]['settings_summary'] = array(); + $table[$name]['settings_edit'] = array(); $table['#field_rows'][] = $name; } + $form['settings'] = $table; // Custom display settings. @@ -834,11 +942,73 @@ function field_ui_display_overview_form($form, &$form_state, $entity_type, $bund $form['#attached']['js'][] = drupal_get_path('module', 'field_ui') . '/field_ui.js'; $form['#attached']['css'][] = drupal_get_path('module', 'field_ui') . '/field_ui.css'; + drupal_add_js(array('fieldDefaultFormatters' => $default_formatters), 'setting'); return $form; } + +/** + * Form submit handler for the formatter settings buttons. + */ +function field_ui_formatter_settings_submit($form, &$form_state) { + $trigger = $form_state['triggering_element']; + $field_name = $trigger['#field_name']; + $op = $trigger['#op']; + + switch ($op) { + case 'edit': + // Store the field whose settings are currently being edited. + $form_state['formatter_settings_edit'] = $field_name; + break; + + case 'update': + // Store the saved settings. + $values = $form_state['values']['settings'][$field_name]['settings_edit_form']['settings']; + $form_state['formatter_settings'][$field_name] = $values; + // Fall-through to the 'cancel' case. + case 'cancel': + // Unset the field as being currently edited. + $form_state['formatter_settings_edit'] = NULL; + break; + } + + $form_state['rebuild'] = TRUE; +} + +/** + * AJAX handler for the formatter settings buttons. + */ +function field_ui_formatter_settings_js($form, &$form_state) { + $trigger = $form_state['triggering_element']; + $field_name = $trigger['#field_name']; + $op = $trigger['#op']; + + // Apply the AJAX effect to updated elements. + switch ($op) { + case 'change_type': + $updated = array('settings_summary'); + break; + + case 'edit': + $updated = array('settings_edit_form'); + break; + + case 'update': + case 'cancel': + $updated = array('type', 'settings_summary', 'settings_edit'); + break; + } + foreach ($updated as $key) { + $element = &$form['settings'][$field_name][$key]; + $element['#prefix'] = '<div class="ajax-new-content">' . (isset($element['#prefix']) ? $element['#prefix'] : ''); + $element['#suffix'] = (isset($element['#suffix']) ? $element['#suffix'] : '') . '</div>'; + } + + return $form['settings']; +} + /** * Theme preprocess function for field_ui-display-overview-table.tpl.php. */ @@ -867,17 +1037,15 @@ function template_preprocess_field_ui_display_overview_table(&$vars) { $row = new stdClass(); foreach (element_children($element) as $child) { - if (array_key_exists('label', $element[$child])) { - $row->{$child} = new stdClass(); - $row->{$child}->label = drupal_render($element[$child]['label']); - $row->{$child}->type = drupal_render($element[$child]['type']); - } - else { - $row->{$child} = drupal_render($element[$child]); - } + $row->{$child} = drupal_render($element[$child]); } + $row->settings_class = (!empty($element['#settings_class']) ? $element['#settings_class'] : ''); $row->class = 'draggable'; + if (isset($element['#settings_editing'])) { + $row->class .= ' field-formatter-settings-editing'; + } $row->label_class = 'label-field'; + $row->id = 'row-' . strtr($key, '_', '-'); $rows[$visibility][] = $row; } } @@ -897,7 +1065,29 @@ function field_ui_display_overview_form_submit($form, &$form_state) { // Save data for 'regular' fields. foreach ($form['#fields'] as $field_name) { $instance = field_info_instance($entity_type, $field_name, $bundle); - $instance['display'][$view_mode] = $form_values['settings'][$field_name]; + $values = $form_values['settings'][$field_name]; + // Get formatter settings. They lie either directly in submitted form + // values (if the whole form was submitted while some formatter + // settings were being edited), or have been persisted in + // $form_state. + $settings = $instance['display'][$view_mode]['settings']; + if (isset($values['settings_edit_form']['settings'])) { + $settings = $values['settings_edit_form']['settings']; + } + elseif (isset($form_state['formatter_settings'][$field_name])) { + $settings = $form_state['formatter_settings'][$field_name]; + } + + // Only save settings actually used by the selected formatter. + $default_settings = field_info_formatter_settings($values['type']); + $settings = array_intersect_key($settings, $default_settings); + + $instance['display'][$view_mode] = array( + 'label' => $values['label'], + 'type' => $values['type'], + 'weight' => $values['weight'], + 'settings' => $settings, + ); field_update_instance($instance); } diff --git a/modules/field_ui/field_ui.api.php b/modules/field_ui/field_ui.api.php index e224ce94e..0db4c01d3 100644 --- a/modules/field_ui/field_ui.api.php +++ b/modules/field_ui/field_ui.api.php @@ -131,6 +131,71 @@ function hook_field_widget_settings_form($field, $instance) { return $form; } + +/** + * Returns form elements for a formatter's settings. + * + * @param $field + * The field structure being configured. + * @param $instance + * The instance structure being configured. + * @param $view_mode + * The view mode being configured. + * @param $form + * The (entire) configuration form array, which will usually have no use here. + * @param $form_state + * The form state of the (entire) configuration form. + * + * @return + * The form elements for the formatter settings. + */ +function hook_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) { + $display = $instance['display'][$view_mode]; + $settings = $display['settings']; + + $element = array(); + + if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') { + $element['trim_length'] = array( + '#title' => t('Length'), + '#type' => 'textfield', + '#size' => 20, + '#default_value' => $settings['trim_length'], + '#element_validate' => array('_element_validate_integer_positive'), + '#required' => TRUE, + ); + } + + return $element; + +} + +/** + * Returns a short summary for the current formatter settings of an instance. + * + * @param $field + * The field structure. + * @param $instance + * The instance structure. + * @param $view_mode + * The view mode for which a settings summary is requested. + * + * @return + * A string containing a short summary of the formatter settings. + */ +function hook_field_formatter_settings_summary($field, $instance, $view_mode) { + $display = $instance['display'][$view_mode]; + $settings = $display['settings']; + + $summary = ''; + + if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') { + $summary = t('Length: @chars chars', array('@chars' => $settings['trim_length'])); + } + + return $summary; +} + /** * @} End of "ingroup field_ui_field_type" */ diff --git a/modules/field_ui/field_ui.css b/modules/field_ui/field_ui.css index 6d03c8b61..9f53967cb 100644 --- a/modules/field_ui/field_ui.css +++ b/modules/field_ui/field_ui.css @@ -15,10 +15,37 @@ padding-bottom: .5em; } -/* Manage display */ +/* 'Manage display' overview */ .field-display-overview tr.region-title td { font-weight: bold; } .field-display-overview tr.region-populated { display: none; } +.field-display-overview .field-formatter-summary-cell { + line-height: 1em; +} +.field-display-overview .field-formatter-summary { + float: left; + font-size: 0.9em; +} +.field-display-overview td.field-formatter-summary-cell span.warning { + display: block; + float: left; + margin-right: .5em; +} +.field-display-overview .field-formatter-settings-edit-wrapper { + float: right; +} +.field-display-overview .field-formatter-settings-edit { + float: right; +} +.field-display-overview tr.field-formatter-settings-editing td { + vertical-align: top; +} +.field-display-overview tr.field-formatter-settings-editing .field-formatter-type { + display: none; +} +.field-display-overview .field-formatter-settings-edit-form .formatter-name{ + font-weight: bold; +}
\ No newline at end of file diff --git a/modules/field_ui/field_ui.js b/modules/field_ui/field_ui.js index 02b8b79ce..86a8515fb 100644 --- a/modules/field_ui/field_ui.js +++ b/modules/field_ui/field_ui.js @@ -134,6 +134,8 @@ Drupal.behaviors.fieldManageDisplayDrag = { var value = 'hidden'; } $select.val(value); + // Fire AJAX update of formatter settings. + $select.change(); } $select.removeData('noUpdate'); } |