Index: misc/tabledrag.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tabledrag.js,v
retrieving revision 1.38
diff -u -r1.38 tabledrag.js
--- misc/tabledrag.js 18 May 2010 06:46:45 -0000 1.38
+++ misc/tabledrag.js 29 May 2010 14:10:56 -0000
@@ -451,7 +451,7 @@
self.rowObject.markChanged();
if (self.changed == false) {
- $(Drupal.theme('tableDragChangedWarning')).insertBefore(self.table).hide().fadeIn('slow');
+ self.rowObject.addChangedWarning();
self.changed = true;
}
}
@@ -1056,6 +1056,10 @@
}
};
+Drupal.tableDrag.prototype.row.prototype.addChangedWarning = function () {
+ $(Drupal.theme('tableDragChangedWarning')).insertBefore(this.table).hide().fadeIn('slow');
+}
+
/**
* Stub function. Allows a custom handler when a row is indented.
*/
Index: modules/field_ui/field_ui.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.js,v
retrieving revision 1.3
diff -u -r1.3 field_ui.js
--- modules/field_ui/field_ui.js 23 May 2010 19:10:23 -0000 1.3
+++ modules/field_ui/field_ui.js 29 May 2010 14:10:57 -0000
@@ -102,6 +102,20 @@
checkEmptyRegions(this.table, this);
};
+ // The AJAX behavior on formatter settings updates the whole table, so we
+ // make sure the 'Save' warning is displayed only once on the page.
+ tableDrag.row.prototype.addChangedWarning = function () {
+ if (!$('#field-settings-changed-warning').length) {
+ $(Drupal.theme('tableDragChangedWarning')).insertBefore(this.table).hide().fadeIn('slow');
+ }
+ }
+
+ // Custom message with an HTML id so that addChangedWarning() can avoid
+ // duplicates.
+ Drupal.theme.prototype.tableDragChangedWarning = function () {
+ return '
' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t('Changes made in this table will not be saved until the form is submitted.') + '
';
+ };
+
// Add a handler to update the formatter selector when a row is dropped in
// or out of the 'Hidden' section.
tableDrag.onDrop = function () {
@@ -134,6 +148,8 @@
var value = 'hidden';
}
$select.val(value);
+ // Fire AJAX update of formatter settings.
+ $select.change();
}
$select.removeData('noUpdate');
}
Index: modules/field_ui/field_ui-display-overview-table.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui-display-overview-table.tpl.php,v
retrieving revision 1.2
diff -u -r1.2 field_ui-display-overview-table.tpl.php
--- modules/field_ui/field_ui-display-overview-table.tpl.php 26 May 2010 07:49:52 -0000 1.2
+++ modules/field_ui/field_ui-display-overview-table.tpl.php 29 May 2010 14:10:56 -0000
@@ -16,13 +16,17 @@
*/
?>
+
+
+
*
+
|
|
|
- |
+ |
@@ -37,6 +41,9 @@
weight . $row->hidden_name; ?> |
label)) print $row->label; ?> |
type; ?> |
+ settings_class) :?> class="settings_class?>">
+ settings_wrapper) ? $row->settings_wrapper : ' '; ?>
+ |
@@ -52,9 +59,11 @@
weight . $row->hidden_name; ?> |
label)) print $row->label; ?> |
type; ?> |
+ |
+
Index: modules/field_ui/field_ui.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.admin.inc,v
retrieving revision 1.51
diff -u -r1.51 field_ui.admin.inc
--- modules/field_ui/field_ui.admin.inc 23 May 2010 19:10:23 -0000 1.51
+++ modules/field_ui/field_ui.admin.inc 29 May 2010 14:10:57 -0000
@@ -591,6 +591,7 @@
$table = array(
'#theme' => 'field_ui_display_overview_table',
'#field_rows' => array(),
+ '#settings_changed' => FALSE,
'#tree' => TRUE,
);
@@ -632,7 +633,109 @@
'#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,
);
+
+ // Formatter 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,
+ );
+
+ // Check the currently selected formatter, and merge persisted values for
+ // formatter settings.
+ $settings_changed = FALSE;
+ 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];
+ $settings_changed = TRUE;
+ }
+ else {
+ $settings = $display['settings'];
+ if (!is_array($settings)) {
+ dsm($field_name);
+ dsm($display);
+ }
+ }
+ //$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;
+
+ if ($settings_changed) {
+ $table['#settings_changed'] = TRUE;
+ }
+
+ if (isset($form_state['formatter_settings_edit']) && $form_state['formatter_settings_edit'] == $name) {
+ // We are currently editing this field's formatter settings. Display
+ // the settings form, and submit buttons.
+ $additions = module_invoke($formatter['module'], 'field_formatter_settings_form', $field, $instance, $view_mode);
+ if (is_array($additions)) {
+ $table[$name]['settings_wrapper']['settings'] = $additions;
+ }
+ $table[$name]['#settings_class'] = 'field-formatter-settings-editing';
+ $table[$name]['settings_wrapper']['actions'] = array('#type' => 'actions');
+ $table[$name]['settings_wrapper']['actions']['save_settings'] = $base_button + array(
+ '#type' => 'submit',
+ '#name' => $name . '_formatter_settings_save',
+ '#value' => t('Save'),
+ '#attributes' => array('class' => array('field-formatter-settings-save')),
+ '#op' => 'save',
+ );
+ $table[$name]['settings_wrapper']['actions']['cancel_settings'] = $base_button + array(
+ '#type' => 'submit',
+ '#name' => $name . '_formatter_settings_cancel',
+ '#value' => t('Cancel'),
+ '#attributes' => array('class' => array('field-formatter-settings-cancel')),
+ '#op' => 'cancel',
+ // Do not check errors for the 'Cancel' button.
+ '#limit_validation_errors' => array(),
+ );
+ $table[$name]['type']['#ajax'] += array(
+ 'trigger_as' => array('name' => $name . '_formatter_settings_save'),
+ );
+ }
+ else {
+ // Display a summary of the current formatter settings.
+ $summary = module_invoke($formatter['module'], 'field_formatter_settings_summary', $field, $instance, $view_mode);
+ if ($summary) {
+ $table[$name]['settings_wrapper']['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(),
+ );
+ $table[$name]['settings_wrapper']['summary'] = array(
+ '#markup' => $summary,
+ );
+ if ($settings_changed) {
+ $table[$name]['#settings_class'] = 'field-formatter-settings-changed';
+ $table[$name]['settings_wrapper']['summary']['#prefix'] = '* ';
+ }
+ }
+ }
$table['#field_rows'][] = $name;
// Collect default formatters for the JS script.
@@ -662,6 +765,7 @@
);
$table['#field_rows'][] = $name;
}
+
$form['settings'] = $table;
// Custom display settings.
@@ -703,6 +807,50 @@
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 'save':
+ // Store the saved settings.
+ $values = $form_state['values']['settings'][$field_name]['settings_wrapper']['settings'];
+ $form_state['formatter_settings'][$field_name] = $values;
+ // Fall-through to the 'cancel' case.
+ case 'cancel':
+ // Unset the field as being currently edited.
+ unset($form_state['formatter_settings_edit']);
+ 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'];
+
+ $element = &$form['settings'][$field_name]['settings_wrapper'];
+ // Add a DIV to receive the AJAX effect.
+ $element['#prefix'] = '' . (isset($element['#prefix']) ? $element['#prefix'] : '');
+ $element['#suffix'] = (isset($element['#suffix']) ? $element['#suffix'] : '') . '
';
+
+ return $form['settings'];
+}
+
/**
* Theme preprocess function for field_ui-display-overview-table.tpl.php.
*/
@@ -731,15 +879,9 @@
$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';
$row->label_class = 'label-field';
$rows[$visibility][] = $row;
@@ -747,6 +889,7 @@
}
$vars['rows'] = $rows;
+ $vars['changed_warning'] = $elements['#settings_changed'];
}
/**
@@ -761,7 +904,25 @@
// 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_wrapper']['settings'])) {
+ $settings = $values['settings_wrapper']['settings'];
+ }
+ elseif (isset($form_state['formatter_settings'][$field_name])) {
+ $settings = $form_state['formatter_settings'][$field_name];
+ }
+
+ $instance['display'][$view_mode] = array(
+ 'label' => $values['label'],
+ 'type' => $values['type'],
+ 'weight' => $values['weight'],
+ 'settings' => $settings,
+ );
field_update_instance($instance);
}
Index: modules/field_ui/field_ui.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.css,v
retrieving revision 1.2
diff -u -r1.2 field_ui.css
--- modules/field_ui/field_ui.css 23 May 2010 19:10:23 -0000 1.2
+++ modules/field_ui/field_ui.css 29 May 2010 14:10:57 -0000
@@ -23,3 +23,27 @@
.field-display-overview tr.region-populated {
display: none;
}
+.field-display-overview .field-formatter-settings-edit {
+ background: none;
+ border: 0;
+ margin: 0;
+ padding: 0;
+ border-radius: 0;
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ vertical-align: -3px;
+}
+.field-display-overview .field-formatter-settings-save,
+.field-display-overview .field-formatter-settings-cancel {
+ margin: 10px 0;
+}
+.field-display-overview td.field-formatter-settings-changed {
+ background: #FFFFBB;
+}
+.field-display-overview td.field-formatter-settings-editing {
+ background: #CCFFCC;
+}
+.field-display-overview tr.drag td.field-formatter-settings-changed,
+.field-display-overview tr.drag td.field-formatter-settings-editing {
+ background: #FFEE77;
+}
\ No newline at end of file
Index: modules/field_ui/field_ui.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.api.php,v
retrieving revision 1.6
diff -u -r1.6 field_ui.api.php
--- modules/field_ui/field_ui.api.php 4 May 2010 16:11:08 -0000 1.6
+++ modules/field_ui/field_ui.api.php 29 May 2010 14:10:57 -0000
@@ -131,6 +131,63 @@
return $form;
}
+
+/**
+ * Returns a form for a formatter's settings.
+ *
+ * @param $field
+ * The field structure being configured.
+ * @param $instance
+ * The instance structure being configured.
+ *
+ * @return
+ * The form definition for the formatter settings.
+ */
+function hook_field_formatter_settings_form($field, $instance, $view_mode) {
+ $display = $instance['display'][$view_mode];
+ $settings = $display['settings'];
+
+ $form = array();
+
+ if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') {
+ $form['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 $form;
+
+}
+
+/**
+ * Returns a short summary for the current formatter settings of an instance.
+ *
+ * @param $field
+ * The field structure being configured.
+ * @param $instance
+ * The instance structure being configured.
+ *
+ * @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;
+}
+
/**
* Provide information on view mode tabs for an entity type.
*
Index: modules/field/modules/text/text.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v
retrieving revision 1.54
diff -u -r1.54 text.module
--- modules/field/modules/text/text.module 6 May 2010 05:59:31 -0000 1.54
+++ modules/field/modules/text/text.module 29 May 2010 14:10:56 -0000
@@ -249,6 +249,7 @@
'text_trimmed' => array(
'label' => t('Trimmed'),
'field types' => array('text', 'text_long', 'text_with_summary'),
+ 'settings' => array('trim_length' => 600),
),
// The 'summary or trimmed' field formatter for text_with_summary
@@ -258,11 +259,51 @@
'text_summary_or_trimmed' => array(
'label' => t('Summary or trimmed'),
'field types' => array('text_with_summary'),
+ 'settings' => array('trim_length' => 600),
),
);
}
/**
+ * Implements hook_field_formatter_settings_form().
+ */
+function text_field_formatter_settings_form($field, $instance, $view_mode) {
+ $display = $instance['display'][$view_mode];
+ $settings = $display['settings'];
+
+ $form = array();
+
+ if ($display['type'] == 'text_trimmed' || $display['type'] == 'text_summary_or_trimmed') {
+ $form['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 $form;
+}
+
+/**
+ * Implements hook_field_formatter_settings_summary().
+ */
+function text_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: @length characters', array('@length' => $settings['trim_length']));
+ }
+
+ return $summary;
+}
+
+/**
* Implements hook_field_formatter_view().
*/
function text_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
Index: modules/image/image.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/image/image.field.inc,v
retrieving revision 1.21
diff -u -r1.21 image.field.inc
--- modules/image/image.field.inc 30 Apr 2010 12:53:47 -0000 1.21
+++ modules/image/image.field.inc 29 May 2010 14:10:57 -0000
@@ -428,14 +428,17 @@
'image' => array(
'label' => t('Image'),
'field types' => array('image'),
+ 'settings' => array('foo' => 1),
),
'image_link_content' => array(
'label' => t('Image linked to content'),
'field types' => array('image'),
+ 'settings' => array('foo' => 1),
),
'image_link_file' => array(
'label' => t('Image linked to file'),
'field types' => array('image'),
+ 'settings' => array('foo' => 1),
),
);
@@ -443,14 +446,17 @@
$formatters['image__' . $style['name']] = array(
'label' => t('Image "@style"', array('@style' => $style['name'])),
'field types' => array('image'),
+ 'settings' => array('foo' => 1),
);
$formatters['image_link_content__' . $style['name']] = array(
'label' => t('Image "@style" linked to content', array('@style' => $style['name'])),
'field types' => array('image'),
+ 'settings' => array('foo' => 1),
);
$formatters['image_link_file__' . $style['name']] = array(
'label' => t('Image "@style" linked to file', array('@style' => $style['name'])),
'field types' => array('image'),
+ 'settings' => array('foo' => 1),
);
}
@@ -458,6 +464,39 @@
}
/**
+ * Implements hook_field_formatter_settings_form().
+ */
+function image_field_formatter_settings_form($field, $instance, $view_mode) {
+ $display = $instance['display'][$view_mode];
+ $settings = $display['settings'];
+
+ $form = array();
+
+ $form['foo'] = array(
+ '#title' => t('foo'),
+ '#type' => 'textfield',
+ '#size' => 20,
+ '#default_value' => $settings['foo'],
+ '#element_validate' => array('_element_validate_integer_positive'),
+ '#required' => TRUE,
+ );
+
+ return $form;
+}
+
+/**
+ * Implements hook_field_formatter_settings_summary().
+ */
+function image_field_formatter_settings_summary($field, $instance, $view_mode) {
+ $display = $instance['display'][$view_mode];
+ $settings = $display['settings'];
+
+ $summary = t('Foo: @foo', array('@foo' => $settings['foo']));
+
+ return $summary;
+}
+
+/**
* Implements hook_field_formatter_view().
*/
function image_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {