summaryrefslogtreecommitdiff
path: root/modules/field_ui
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2010-07-17 19:19:39 +0000
committerDries Buytaert <dries@buytaert.net>2010-07-17 19:19:39 +0000
commitb135d644fe726e763c0a7f75ba47c4eeab4bfb88 (patch)
treecd2c1983f291527f6708606eeb8aed9e9bbaefe2 /modules/field_ui
parentecc7ce08754ca321110c25ca29567f9726813637 (diff)
downloadbrdo-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.php35
-rw-r--r--modules/field_ui/field_ui.admin.inc210
-rw-r--r--modules/field_ui/field_ui.api.php65
-rw-r--r--modules/field_ui/field_ui.css29
-rw-r--r--modules/field_ui/field_ui.js2
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');
}