#323112 by dmitrig01, kkaefer, quicksketch, frando and many many more: Now presenting... Vertical Tabs. Fantastic new UI improvement for node forms and hopefully more in the future.
							parent
							
								
									f278da9e50
								
							
						
					
					
						commit
						e888f0061c
					
				| 
						 | 
				
			
			@ -3368,6 +3368,28 @@ function drupal_render(&$elements) {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add additional CSS and JavaScript files associated with this element.
 | 
			
		||||
  foreach (array('css', 'js') as $kind) {
 | 
			
		||||
    if (!empty($elements['#attached_' . $kind]) && is_array($elements['#attached_' . $kind])) {
 | 
			
		||||
      foreach ($elements['#attached_' . $kind] as $data => $options) {
 | 
			
		||||
        // If the value is not an array, it's a filename and passed as first
 | 
			
		||||
        // (and only) argument.
 | 
			
		||||
        if (!is_array($options)) {
 | 
			
		||||
          $data = $options;
 | 
			
		||||
          $options = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        // When drupal_add_js with 'type' => 'setting' is called, the first
 | 
			
		||||
        // parameter ($data) is an array. Arrays can't be keys in PHP, so we
 | 
			
		||||
        // have to get $data from the value array.
 | 
			
		||||
        if (is_numeric($data)) {
 | 
			
		||||
          $data = $options['data'];
 | 
			
		||||
          unset($options['data']);
 | 
			
		||||
        }
 | 
			
		||||
        call_user_func('drupal_add_' . $kind, $data, $options);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get the children of the element, sorted by weight.
 | 
			
		||||
  $children = element_children($elements, TRUE);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3750,6 +3772,9 @@ function drupal_common_theme() {
 | 
			
		|||
    'text_format_wrapper' => array(
 | 
			
		||||
      'arguments' => array('element' => NULL),
 | 
			
		||||
    ),
 | 
			
		||||
    'vertical_tabs' => array(
 | 
			
		||||
      'arguments' => array('element' => NULL),
 | 
			
		||||
    ),
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -227,6 +227,7 @@ function form_state_defaults() {
 | 
			
		|||
    'method' => 'post',
 | 
			
		||||
    'rerender' => TRUE,
 | 
			
		||||
    'programmed' => FALSE,
 | 
			
		||||
    'groups' => array(),
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -286,6 +287,10 @@ function drupal_rebuild_form($form_id, &$form_state, $form_build_id = NULL) {
 | 
			
		|||
  // then process the form for rendering.
 | 
			
		||||
  $form_state['input'] = array();
 | 
			
		||||
 | 
			
		||||
  // Also clear out all group associations as these might be different
 | 
			
		||||
  // when rerendering the form.
 | 
			
		||||
  $form_state['groups'] = array();
 | 
			
		||||
 | 
			
		||||
  // Do not call drupal_process_form(), since it would prevent the rebuilt form
 | 
			
		||||
  // to submit.
 | 
			
		||||
  $form = form_builder($form_id, $form, $form_state);
 | 
			
		||||
| 
						 | 
				
			
			@ -939,7 +944,8 @@ function form_error(&$element, $message = '') {
 | 
			
		|||
/**
 | 
			
		||||
 * Walk through the structured form array, adding any required
 | 
			
		||||
 * properties to each element and mapping the incoming $_POST
 | 
			
		||||
 * data to the proper elements.
 | 
			
		||||
 * data to the proper elements. Also, execute any #process handlers
 | 
			
		||||
 * attached to a specific element.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $form_id
 | 
			
		||||
 *   A unique string identifying the form for validation, submission,
 | 
			
		||||
| 
						 | 
				
			
			@ -972,9 +978,22 @@ function form_builder($form_id, $form, &$form_state) {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!isset($form['#id'])) {
 | 
			
		||||
    $form['#id'] = form_clean_id('edit-' . implode('-', $form['#parents']));
 | 
			
		||||
  }
 | 
			
		||||
  if (isset($form['#input']) && $form['#input']) {
 | 
			
		||||
    _form_builder_handle_input_element($form_id, $form, $form_state, $complete_form);
 | 
			
		||||
  }
 | 
			
		||||
  // Allow for elements to expand to multiple elements, e.g., radios,
 | 
			
		||||
  // checkboxes and files.
 | 
			
		||||
  if (isset($form['#process']) && !$form['#processed']) {
 | 
			
		||||
    foreach ($form['#process'] as $process) {
 | 
			
		||||
      if (drupal_function_exists($process)) {
 | 
			
		||||
        $form = $process($form, $form_state, $complete_form);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $form['#processed'] = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
  $form['#defaults_loaded'] = TRUE;
 | 
			
		||||
 | 
			
		||||
  // We start off assuming all form elements are in the correct order.
 | 
			
		||||
| 
						 | 
				
			
			@ -1062,8 +1081,7 @@ function form_builder($form_id, $form, &$form_state) {
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 * Populate the #value and #name properties of input elements so they
 | 
			
		||||
 * can be processed and rendered. Also, execute any #process handlers
 | 
			
		||||
 * attached to a specific element.
 | 
			
		||||
 * can be processed and rendered.
 | 
			
		||||
 */
 | 
			
		||||
function _form_builder_handle_input_element($form_id, &$form, &$form_state, $complete_form) {
 | 
			
		||||
  if (!isset($form['#name'])) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1080,9 +1098,6 @@ function _form_builder_handle_input_element($form_id, &$form, &$form_state, $com
 | 
			
		|||
    }
 | 
			
		||||
    array_unshift($form['#parents'], $name);
 | 
			
		||||
  }
 | 
			
		||||
  if (!isset($form['#id'])) {
 | 
			
		||||
    $form['#id'] = form_clean_id('edit-' . implode('-', $form['#parents']));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!empty($form['#disabled'])) {
 | 
			
		||||
    $form['#attributes']['disabled'] = 'disabled';
 | 
			
		||||
| 
						 | 
				
			
			@ -1151,16 +1166,6 @@ function _form_builder_handle_input_element($form_id, &$form, &$form_state, $com
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Allow for elements to expand to multiple elements, e.g., radios,
 | 
			
		||||
  // checkboxes and files.
 | 
			
		||||
  if (isset($form['#process']) && !$form['#processed']) {
 | 
			
		||||
    foreach ($form['#process'] as $process) {
 | 
			
		||||
      if (drupal_function_exists($process)) {
 | 
			
		||||
        $form = $process($form, isset($edit) ? $edit : NULL, $form_state, $complete_form);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    $form['#processed'] = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
  form_set_value($form, $form['#value'], $form_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1597,6 +1602,7 @@ function theme_fieldset($element) {
 | 
			
		|||
      $element['#attributes']['class'] .= ' collapsed';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  $element['#attributes']['id'] = $element['#id'];
 | 
			
		||||
 | 
			
		||||
  return '<fieldset' . drupal_attributes($element['#attributes']) . '>' . ($element['#title'] ? '<legend>' . $element['#title'] . '</legend>' : '') . (isset($element['#description']) && $element['#description'] ? '<div class="description">' . $element['#description'] . '</div>' : '') . (!empty($element['#children']) ? $element['#children'] : '') . (isset($element['#value']) ? $element['#value'] : '') . "</fieldset>\n";
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -2143,7 +2149,6 @@ function form_process_checkboxes($element) {
 | 
			
		|||
 *   An associative array containing the properties and children of the
 | 
			
		||||
 *   tableselect element.
 | 
			
		||||
 *   Properties used: header, options, empty, js_select.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 *   A themed HTML string representing the table.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -2186,7 +2191,6 @@ function theme_tableselect($element) {
 | 
			
		|||
 * @param $element
 | 
			
		||||
 *   An associative array containing the properties and children of the
 | 
			
		||||
 *   tableselect element.
 | 
			
		||||
 *
 | 
			
		||||
 * @return
 | 
			
		||||
 *   The processed element.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -2247,6 +2251,142 @@ function form_process_tableselect($element) {
 | 
			
		|||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adds fieldsets to the specified group or adds group members to this
 | 
			
		||||
 * fieldset.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $element
 | 
			
		||||
 *   An associative array containing the properties and children of the
 | 
			
		||||
 *   fieldset.
 | 
			
		||||
 * @param $form_state
 | 
			
		||||
 *   The $form_state array for the form this fieldset belongs to.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   The processed element.
 | 
			
		||||
 */
 | 
			
		||||
function form_process_fieldset(&$element, &$form_state) {
 | 
			
		||||
  $parents = implode('][', $element['#parents']);
 | 
			
		||||
 | 
			
		||||
  // Add this fieldset to a group if one is set and if it's not being
 | 
			
		||||
  // added to itself.
 | 
			
		||||
  if (isset($element['#group']) && $element['#group'] != $parents) {
 | 
			
		||||
    if (isset($form_state['groups'][$element['#group']]) && !empty($form_state['groups'][$element['#group']]['#group_exists'])) {
 | 
			
		||||
      // Trick drupal_render() into believing this has already been output.
 | 
			
		||||
      // The group widget will rerender this later. This only happens when the
 | 
			
		||||
      // group is actually defined ('#group_exists' is TRUE). This prevents
 | 
			
		||||
      // fieldsets from disappearing when the group they are associated to
 | 
			
		||||
      // does not exist.
 | 
			
		||||
      // If the group does not exist yet, the element's #printed value is left
 | 
			
		||||
      // as is. As soon as the group is processed (fieldsets are also groups;
 | 
			
		||||
      // see below), this element's #printed value is set to TRUE to prevent
 | 
			
		||||
      // rendering in the original context.
 | 
			
		||||
      $element['#printed'] = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Store a reference to this fieldset for the vertical tabs processing
 | 
			
		||||
    // function.
 | 
			
		||||
    $form_state['groups'][$element['#group']][] = &$element;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Each fieldset can be a group itself and gets a reference to all
 | 
			
		||||
  // elements in its group.
 | 
			
		||||
  $form_state['groups'][$parents]['#group_exists'] = TRUE;
 | 
			
		||||
  // There might already be elements associated with this group. Since the
 | 
			
		||||
  // group did not exist yet at the time they were added to this group, they
 | 
			
		||||
  // couldn't set #printed to TRUE (see above). We now know that this group
 | 
			
		||||
  // does in fact exist and set #printed to TRUE to prevent rendering in the
 | 
			
		||||
  // original context.
 | 
			
		||||
  foreach (element_children($form_state['groups'][$parents]) as $key) {
 | 
			
		||||
    $form_state['groups'][$parents][$key]['#printed'] = TRUE;
 | 
			
		||||
  }
 | 
			
		||||
  $element['#group_members'] = &$form_state['groups'][$parents];
 | 
			
		||||
 | 
			
		||||
  // Contains form element summary functionalities.
 | 
			
		||||
  drupal_add_js('misc/form.js', array('weight' => JS_LIBRARY + 1));
 | 
			
		||||
 | 
			
		||||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adds members of this group as actual elements for rendering.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $element
 | 
			
		||||
 *   An associative array containing the properties and children of the
 | 
			
		||||
 *   fieldset.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   The modified element with all group members.
 | 
			
		||||
 */
 | 
			
		||||
function form_pre_render_fieldset($element) {
 | 
			
		||||
  if (!empty($element['#group_members'])) {
 | 
			
		||||
    // Add the group members to this fieldset for rendering purposes only.
 | 
			
		||||
    foreach (element_children($element['#group_members']) as $key) {
 | 
			
		||||
      // This was set in form_process_fieldset so that fieldsets which are
 | 
			
		||||
      // added to groups are not rendered at their original location.
 | 
			
		||||
      // drupal_render_children() will set this back to TRUE.
 | 
			
		||||
      unset($element['#group_members'][$key]['#printed']);
 | 
			
		||||
      $element[] = &$element['#group_members'][$key];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Resort the element's children after the group members have been added.
 | 
			
		||||
    $element['#sorted'] = FALSE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a group formatted as vertical tabs.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $element
 | 
			
		||||
 *   An associative array containing the properties and children of the
 | 
			
		||||
 *   fieldset.
 | 
			
		||||
 * @param $form_state
 | 
			
		||||
 *   The $form_state array for the form this vertical tab widget belongs to.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   The processed element.
 | 
			
		||||
 */
 | 
			
		||||
function form_process_vertical_tabs($element, &$form_state) {
 | 
			
		||||
  // To save us from modifying the existing element and changing its #type,
 | 
			
		||||
  // a new form element is created as a child. The default #process hooks
 | 
			
		||||
  // are called automatically by the form renderer and we don't have to do
 | 
			
		||||
  // that manually.
 | 
			
		||||
  $element['group'] = array(
 | 
			
		||||
    '#type' => 'fieldset',
 | 
			
		||||
    '#theme_wrapper' => '',
 | 
			
		||||
    '#parents' => $element['#parents'],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  // The JavaScript stores the currently selected tab in this hidden
 | 
			
		||||
  // field so that the active tab can be restored the next time the
 | 
			
		||||
  // form is rendered, e.g. on preview pages or when form validation
 | 
			
		||||
  // fails.
 | 
			
		||||
  $name = implode('__', $element['#parents']);
 | 
			
		||||
  if (isset($form_state['values'][$name . '__active_tab'])) {
 | 
			
		||||
    $element['#default_tab'] = $form_state['values'][$name . '__active_tab'];
 | 
			
		||||
  }
 | 
			
		||||
  $element[$name . '__active_tab'] = array(
 | 
			
		||||
    '#type' => 'hidden',
 | 
			
		||||
    '#default_value' => $element['#default_tab'],
 | 
			
		||||
    '#attributes' => array('class' => 'vertical-tabs-active-tab'),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return $element;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Makes the element's children fieldsets be vertical tabs.
 | 
			
		||||
 *
 | 
			
		||||
 * @param $element
 | 
			
		||||
 *   An associative array containing the properties and children of the
 | 
			
		||||
 *   fieldset.
 | 
			
		||||
 */
 | 
			
		||||
function theme_vertical_tabs(&$element) {
 | 
			
		||||
  // Add required JavaScript and Stylesheet.
 | 
			
		||||
  drupal_add_js('misc/vertical-tabs.js', array('weight' => JS_DEFAULT - 1));
 | 
			
		||||
  drupal_add_css('misc/vertical-tabs.css');
 | 
			
		||||
 | 
			
		||||
  return '<div class="vertical-tabs-panes">' . $element['#children'] . '</div>';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Theme a form submit button.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,14 @@ Drupal.behaviors.collapse = {
 | 
			
		|||
        fieldset.removeClass('collapsed');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var summary = $('<span class="summary"></span>');
 | 
			
		||||
      fieldset.
 | 
			
		||||
        bind('summaryUpdated', function() {
 | 
			
		||||
          var text = $.trim(fieldset.getSummary());
 | 
			
		||||
          summary.html(text ? ' (' + text + ')' : '');
 | 
			
		||||
        })
 | 
			
		||||
        .trigger('summaryUpdated');
 | 
			
		||||
 | 
			
		||||
      // Turn the legend into a clickable link and wrap the contents of the fieldset
 | 
			
		||||
      // in a div for easier animation
 | 
			
		||||
      var text = this.innerHTML;
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +80,7 @@ Drupal.behaviors.collapse = {
 | 
			
		|||
          }
 | 
			
		||||
          return false;
 | 
			
		||||
        }))
 | 
			
		||||
        .append(summary)
 | 
			
		||||
        .after($('<div class="fieldset-wrapper"></div>')
 | 
			
		||||
        .append(fieldset.children(':not(legend):not(.action)')))
 | 
			
		||||
        .addClass('collapse-processed');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										57
									
								
								misc/form.js
								
								
								
								
							
							
						
						
									
										57
									
								
								misc/form.js
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,63 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieves the summary for the first element.
 | 
			
		||||
 */
 | 
			
		||||
$.fn.getSummary = function() {
 | 
			
		||||
  var callback = this.data('summaryCallback');
 | 
			
		||||
  return (this[0] && callback) ? $.trim(callback(this[0])) : '';
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sets the summary for all matched elements.
 | 
			
		||||
 *
 | 
			
		||||
 * @param callback
 | 
			
		||||
 *   Either a function that will be called each time the summary is
 | 
			
		||||
 *   retrieved or a string (which is returned each time).
 | 
			
		||||
 */
 | 
			
		||||
$.fn.setSummary = function(callback) {
 | 
			
		||||
  var that = this;
 | 
			
		||||
 | 
			
		||||
  // To facilitate things, the callback should always be a function. If it's
 | 
			
		||||
  //  not, we wrap it into an anonymous function which just returns the value.
 | 
			
		||||
  if (typeof callback != 'function') {
 | 
			
		||||
    var val = callback;
 | 
			
		||||
    callback = function() { return val; };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return this
 | 
			
		||||
    .data('summaryCallback', callback)
 | 
			
		||||
    // To prevent duplicate events, the handlers are first removed and then
 | 
			
		||||
    // (re-)added.
 | 
			
		||||
    .unbind('formUpdated.summary')
 | 
			
		||||
    .bind('formUpdated.summary', function() {
 | 
			
		||||
      that.trigger('summaryUpdated');
 | 
			
		||||
    })
 | 
			
		||||
    // The actual summaryUpdated handler doesn't fire when the callback is
 | 
			
		||||
    // changed, so we have to do this manually.
 | 
			
		||||
    .trigger('summaryUpdated');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sends a 'formUpdated' event each time a form element is modified.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.behaviors.formUpdated = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    // These events are namespaced so that we can remove them later.
 | 
			
		||||
    var events = 'change.formUpdated click.formUpdated blur.formUpdated keyup.formUpdated';
 | 
			
		||||
    $(context)
 | 
			
		||||
      // Since context could be an input element itself, it's added back to
 | 
			
		||||
      // the jQuery object and filtered again.
 | 
			
		||||
      .find(':input').andSelf().filter(':input')
 | 
			
		||||
      // To prevent duplicate events, the handlers are first removed and then
 | 
			
		||||
      // (re-)added.
 | 
			
		||||
      .unbind(events).bind(events, function() {
 | 
			
		||||
        $(this).trigger('formUpdated');
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.multiselectSelector = {
 | 
			
		||||
  attach: function(context, settings) {
 | 
			
		||||
    // Automatically selects the right radio button in a multiselect control.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
/* $Id */
 | 
			
		||||
 | 
			
		||||
.vertical-tabs {
 | 
			
		||||
  margin-left: 0;
 | 
			
		||||
  margin-right: 15em;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list {
 | 
			
		||||
  margin-right: -15em;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  float: right;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li.selected {
 | 
			
		||||
  border-left-width: 0;
 | 
			
		||||
  border-right-width: 1px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
/* $Id */
 | 
			
		||||
 | 
			
		||||
.vertical-tabs {
 | 
			
		||||
  margin: 1em 0 1em 15em;
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list {
 | 
			
		||||
  width: 15em;
 | 
			
		||||
  list-style: none;
 | 
			
		||||
  list-style-image: none; /* IE6 */
 | 
			
		||||
  border-top: 1px solid #ccc;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  position: relative; /* IE6 */
 | 
			
		||||
  margin: -1px -100% -1px 0;
 | 
			
		||||
  left: -15em;
 | 
			
		||||
  float: left;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs .vertical-tabs-panes fieldset.vertical-tabs-pane {
 | 
			
		||||
  margin: 0 !important;
 | 
			
		||||
  padding: 0 1em;
 | 
			
		||||
  border: 0;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs .vertical-tabs-panes fieldset.vertical-tabs-pane legend {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Layout of each tab */
 | 
			
		||||
.vertical-tabs-list li {
 | 
			
		||||
  background: #eee;
 | 
			
		||||
  border: 1px solid #ccc;
 | 
			
		||||
  border-top: 0;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
  margin: 0;
 | 
			
		||||
  height: 1%;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li a {
 | 
			
		||||
  display: block;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  padding: 0.5em 0.6em;
 | 
			
		||||
  line-height: 1.3em;
 | 
			
		||||
  height: 1%;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li a:focus {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  z-index: 5;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li a:hover {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li.selected {
 | 
			
		||||
  background: #fff;
 | 
			
		||||
  border-right-width: 0;
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li.selected a:focus {
 | 
			
		||||
  outline: 0;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list li.selected .title {
 | 
			
		||||
  font-weight: bold;
 | 
			
		||||
  color: #000;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs-list .summary {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
.vertical-tabs ul.vertical-tabs-list .summary {
 | 
			
		||||
  line-height: normal;
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,120 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This script transforms a set of fieldsets into a stack of vertical
 | 
			
		||||
 * tabs. Another tab pane can be selected by clicking on the respective
 | 
			
		||||
 * tab.
 | 
			
		||||
 *
 | 
			
		||||
 * Each tab may have a summary which can be updated by another
 | 
			
		||||
 * script. For that to work, each fieldset has an associated 
 | 
			
		||||
 * 'verticalTabCallback' (with jQuery.data() attached to the fieldset),
 | 
			
		||||
 * which is called every time the user performs an update to a form
 | 
			
		||||
 * element inside the tab pane.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.behaviors.verticalTabs = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('.vertical-tabs-panes:not(.vertical-tabs-processed)', context).each(function() {
 | 
			
		||||
      var focusID = $(':hidden.vertical-tabs-active-tab', this).val();
 | 
			
		||||
      var focus;
 | 
			
		||||
      // Create the tab column.
 | 
			
		||||
      var list = $('<ul class="vertical-tabs-list"></ul>');
 | 
			
		||||
      $(this).wrap('<div class="vertical-tabs clearfix"></div>').before(list);
 | 
			
		||||
 | 
			
		||||
      // Transform each fieldset into a tab.
 | 
			
		||||
      $('> fieldset', this).each(function() {
 | 
			
		||||
        var tab = new Drupal.verticalTab({ title: $('> legend', this).text(), fieldset: $(this) });
 | 
			
		||||
        list.append(tab.item);
 | 
			
		||||
        $(this)
 | 
			
		||||
          .removeClass('collapsible collapsed')
 | 
			
		||||
          .addClass('vertical-tabs-pane')
 | 
			
		||||
          .data('verticalTab', tab);
 | 
			
		||||
        if (this.id == focusID) {
 | 
			
		||||
          focus = $(this);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      $('> li:first', list).addClass('first');
 | 
			
		||||
      $('> li:last', list).addClass('last');
 | 
			
		||||
 | 
			
		||||
      if (!focus) {
 | 
			
		||||
        focus = $('> .vertical-tabs-pane:first', this);
 | 
			
		||||
      }
 | 
			
		||||
      focus.data('verticalTab').focus();
 | 
			
		||||
    }).addClass('vertical-tabs-processed');
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The vertical tab object represents a single tab within a tab group.
 | 
			
		||||
 *
 | 
			
		||||
 * @param settings
 | 
			
		||||
 *   An object with the following keys:
 | 
			
		||||
 *   - title: The name of the tab.
 | 
			
		||||
 *   - fieldset: The jQuery object of the fieldset that is the tab pane.
 | 
			
		||||
 */
 | 
			
		||||
Drupal.verticalTab = function(settings) {
 | 
			
		||||
  var that = this;
 | 
			
		||||
  $.extend(this, settings, Drupal.theme('verticalTab', settings));
 | 
			
		||||
 | 
			
		||||
  this.link.click(function() {
 | 
			
		||||
    that.focus();
 | 
			
		||||
    return false;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  this.fieldset
 | 
			
		||||
    .bind('summaryUpdated', function() {
 | 
			
		||||
      that.updateSummary();
 | 
			
		||||
    })
 | 
			
		||||
    .trigger('summaryUpdated');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Drupal.verticalTab.prototype = {
 | 
			
		||||
  // Displays the tab's content pane.
 | 
			
		||||
  focus: function() {
 | 
			
		||||
    this.fieldset
 | 
			
		||||
      .siblings('fieldset.vertical-tabs-pane')
 | 
			
		||||
        .each(function() {
 | 
			
		||||
          var tab = $(this).data('verticalTab');
 | 
			
		||||
          tab.fieldset.hide();
 | 
			
		||||
          tab.item.removeClass('selected');
 | 
			
		||||
        })
 | 
			
		||||
        .end()
 | 
			
		||||
      .show()
 | 
			
		||||
      .siblings(':hidden.vertical-tabs-active-tab')
 | 
			
		||||
        .val(this.fieldset.attr('id'));
 | 
			
		||||
    this.item.addClass('selected');
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  // Updates the tab's summary.
 | 
			
		||||
  updateSummary: function() {
 | 
			
		||||
    this.summary.html(this.fieldset.getSummary());
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Theme function for a vertical tab.
 | 
			
		||||
 *
 | 
			
		||||
 * @param settings
 | 
			
		||||
 *   An object with the following keys:
 | 
			
		||||
 *   - title: The name of the tab.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   This function has to return an object with at least these keys:
 | 
			
		||||
 *   - item: The root tab jQuery element
 | 
			
		||||
 *   - link: The anchor tag that acts as the clickable area of the tab
 | 
			
		||||
 *       (jQuery version)
 | 
			
		||||
 *   - summary: The jQuery element that contains the tab summary
 | 
			
		||||
 */
 | 
			
		||||
Drupal.theme.prototype.verticalTab = function(settings) {
 | 
			
		||||
  var tab = {};
 | 
			
		||||
  tab.item = $('<li class="vertical-tab-button"></li>')
 | 
			
		||||
    .append(tab.link = $('<a href="#"></a>')
 | 
			
		||||
      .append(tab.title = $('<span class="title"></span>').text(settings.title))
 | 
			
		||||
      .append(tab.summary = $('<span class="summary"></span>')
 | 
			
		||||
    )
 | 
			
		||||
  );
 | 
			
		||||
  return tab;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +35,9 @@
 | 
			
		|||
  margin-top: 0;
 | 
			
		||||
  margin-bottom: 0;
 | 
			
		||||
}
 | 
			
		||||
html.js #edit-book-pick-book {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
#edit-book-bid-wrapper .description {
 | 
			
		||||
  clear: both;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.bookFieldsetSummaries = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('fieldset#edit-book', context).setSummary(function(context) {
 | 
			
		||||
      var val = $('#edit-book-bid').val();
 | 
			
		||||
 | 
			
		||||
      if (val === '0') {
 | 
			
		||||
        return Drupal.t('Not in book');
 | 
			
		||||
      }
 | 
			
		||||
      else if (val === 'new') {
 | 
			
		||||
        return Drupal.t('New book');
 | 
			
		||||
      }
 | 
			
		||||
      else {
 | 
			
		||||
        return Drupal.checkPlain($('#edit-book-bid :selected').text());
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -415,7 +415,6 @@ function _book_parent_select($book_link) {
 | 
			
		|||
function _book_add_form_elements(&$form, $node) {
 | 
			
		||||
  // Need this for AJAX.
 | 
			
		||||
  $form['#cache'] = TRUE;
 | 
			
		||||
  drupal_add_js("if (Drupal.jsEnabled) { jQuery(function() { jQuery('#edit-book-pick-book').css('display', 'none'); }); }", 'inline');
 | 
			
		||||
 | 
			
		||||
  $form['book'] = array(
 | 
			
		||||
    '#type' => 'fieldset',
 | 
			
		||||
| 
						 | 
				
			
			@ -423,6 +422,8 @@ function _book_add_form_elements(&$form, $node) {
 | 
			
		|||
    '#weight' => 10,
 | 
			
		||||
    '#collapsible' => TRUE,
 | 
			
		||||
    '#collapsed' => TRUE,
 | 
			
		||||
    '#group' => 'additional_settings',
 | 
			
		||||
    '#attached_js' => array(drupal_get_path('module', 'book') . '/book.js'),
 | 
			
		||||
    '#tree' => TRUE,
 | 
			
		||||
    '#attributes' => array('class' => 'book-outline-form'),
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.commentFieldsetSummaries = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('fieldset#edit-comment-settings', context).setSummary(function(context) {
 | 
			
		||||
      return Drupal.checkPlain($('input:checked', context).parent().text());
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -580,6 +580,8 @@ function comment_form_alter(&$form, $form_state, $form_id) {
 | 
			
		|||
      '#title' => t('Comment settings'),
 | 
			
		||||
      '#collapsible' => TRUE,
 | 
			
		||||
      '#collapsed' => TRUE,
 | 
			
		||||
      '#group' => 'additional_settings',
 | 
			
		||||
      '#attached_js' => array(drupal_get_path('module', 'comment') . '/comment-node-form.js'),
 | 
			
		||||
      '#weight' => 30,
 | 
			
		||||
    );
 | 
			
		||||
    $comment_count = isset($node->nid) ? db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField() : 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,13 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.menuFieldsetSummaries = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('fieldset#edit-menu', context).setSummary(function(context) {
 | 
			
		||||
      return Drupal.checkPlain($('#edit-menu-link-title', context).val()) || Drupal.t('Not in menu');
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -395,6 +395,8 @@ function menu_form_alter(&$form, $form_state, $form_id) {
 | 
			
		|||
      '#access' => user_access('administer menu'),
 | 
			
		||||
      '#collapsible' => TRUE,
 | 
			
		||||
      '#collapsed' => FALSE,
 | 
			
		||||
      '#group' => 'additional_settings',
 | 
			
		||||
      '#attached_js' => array(drupal_get_path('module', 'menu') . '/menu.js'),
 | 
			
		||||
      '#tree' => TRUE,
 | 
			
		||||
      '#weight' => -2,
 | 
			
		||||
      '#attributes' => array('class' => 'menu-item-form'),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.nodeFieldsetSummaries = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('fieldset#edit-revision-information', context).setSummary(function(context) {
 | 
			
		||||
      return $('#edit-revision', context).is(':checked') ?
 | 
			
		||||
        Drupal.t('New revision') :
 | 
			
		||||
        Drupal.t('No revision');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('fieldset#edit-author', context).setSummary(function(context) {
 | 
			
		||||
      var name = $('#edit-name').val(), date = $('#edit-date').val();
 | 
			
		||||
      return date ?
 | 
			
		||||
        Drupal.t('By @name on @date', { '@name': name, '@date': date }) :
 | 
			
		||||
        Drupal.t('By @name', { '@name': name });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('fieldset#edit-options', context).setSummary(function(context) {
 | 
			
		||||
      var vals = [];
 | 
			
		||||
 | 
			
		||||
      $('input:checked', context).parent().each(function() {
 | 
			
		||||
        vals.push(Drupal.checkPlain($.trim($(this).text())));
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (!$('#edit-status', context).is(':checked')) {
 | 
			
		||||
        vals.unshift(Drupal.t('Not published'));
 | 
			
		||||
      }
 | 
			
		||||
      return vals.join(', ');
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +152,10 @@ function node_form(&$form_state, $node) {
 | 
			
		|||
 | 
			
		||||
  $form['#node'] = $node;
 | 
			
		||||
 | 
			
		||||
  $form['additional_settings'] = array(
 | 
			
		||||
    '#type' => 'vertical_tabs',
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  // Add a log field if the "Create new revision" option is checked, or if the
 | 
			
		||||
  // current user has the ability to check that option.
 | 
			
		||||
  if (!empty($node->revision) || user_access('administer nodes')) {
 | 
			
		||||
| 
						 | 
				
			
			@ -161,6 +165,8 @@ function node_form(&$form_state, $node) {
 | 
			
		|||
      '#collapsible' => TRUE,
 | 
			
		||||
      // Collapsed by default when "Create new revision" is unchecked
 | 
			
		||||
      '#collapsed' => !$node->revision,
 | 
			
		||||
      '#group' => 'additional_settings',
 | 
			
		||||
      '#attached_js' => array(drupal_get_path('module', 'node') . '/node.js'),
 | 
			
		||||
      '#weight' => 20,
 | 
			
		||||
    );
 | 
			
		||||
    $form['revision_information']['revision'] = array(
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +178,7 @@ function node_form(&$form_state, $node) {
 | 
			
		|||
    $form['revision_information']['log'] = array(
 | 
			
		||||
      '#type' => 'textarea',
 | 
			
		||||
      '#title' => t('Revision log message'),
 | 
			
		||||
      '#rows' => 2,
 | 
			
		||||
      '#rows' => 4,
 | 
			
		||||
      '#description' => t('Provide an explanation of the changes you are making. This will help other authors understand your motivations.'),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -184,6 +190,8 @@ function node_form(&$form_state, $node) {
 | 
			
		|||
    '#title' => t('Authoring information'),
 | 
			
		||||
    '#collapsible' => TRUE,
 | 
			
		||||
    '#collapsed' => TRUE,
 | 
			
		||||
    '#group' => 'additional_settings',
 | 
			
		||||
    '#attached_js' => array(drupal_get_path('module', 'node') . '/node.js'),
 | 
			
		||||
    '#weight' => 90,
 | 
			
		||||
  );
 | 
			
		||||
  $form['author']['name'] = array(
 | 
			
		||||
| 
						 | 
				
			
			@ -213,6 +221,8 @@ function node_form(&$form_state, $node) {
 | 
			
		|||
    '#title' => t('Publishing options'),
 | 
			
		||||
    '#collapsible' => TRUE,
 | 
			
		||||
    '#collapsed' => TRUE,
 | 
			
		||||
    '#group' => 'additional_settings',
 | 
			
		||||
    '#attached_js' => array(drupal_get_path('module', 'node') . '/node.js'),
 | 
			
		||||
    '#weight' => 95,
 | 
			
		||||
  );
 | 
			
		||||
  $form['options']['status'] = array(
 | 
			
		||||
| 
						 | 
				
			
			@ -283,7 +293,7 @@ function node_body_field(&$node, $label, $word_count) {
 | 
			
		|||
  $form = array(
 | 
			
		||||
    '#after_build' => array('node_teaser_js', 'node_teaser_include_verify'));
 | 
			
		||||
 | 
			
		||||
  $form['#prefix'] = '<div class="body-field-wrapper">';
 | 
			
		||||
  $form['#prefix'] = '<div class="body-field-wrapper clearfix">';
 | 
			
		||||
  $form['#suffix'] = '</div>';
 | 
			
		||||
 | 
			
		||||
  $form['teaser_js'] = array(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.pathFieldsetSummaries = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('fieldset#edit-path', context).setSummary(function(context) {
 | 
			
		||||
      var path = $('#edit-path-1').val();
 | 
			
		||||
 | 
			
		||||
      return path ?
 | 
			
		||||
        Drupal.t('Alias: @alias', { '@alias': path }) :
 | 
			
		||||
        Drupal.t('No alias');
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -194,6 +194,8 @@ function path_form_alter(&$form, $form_state, $form_id) {
 | 
			
		|||
      '#title' => t('URL path settings'),
 | 
			
		||||
      '#collapsible' => TRUE,
 | 
			
		||||
      '#collapsed' => empty($path),
 | 
			
		||||
      '#group' => 'additional_settings',
 | 
			
		||||
      '#attached_js' => array(drupal_get_path('module', 'path') . '/path.js'),
 | 
			
		||||
      '#access' => user_access('create url aliases'),
 | 
			
		||||
      '#weight' => 30,
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -320,11 +320,19 @@ html.js fieldset.collapsed * {
 | 
			
		|||
}
 | 
			
		||||
html.js fieldset.collapsed legend {
 | 
			
		||||
  display: block;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
}
 | 
			
		||||
html.js fieldset.collapsible legend a {
 | 
			
		||||
  display: inline;
 | 
			
		||||
  padding-left: 15px; /* LTR */
 | 
			
		||||
  background: url(../../misc/menu-expanded.png) 5px 75% no-repeat; /* LTR */
 | 
			
		||||
}
 | 
			
		||||
html.js fieldset.collapsible legend span.summary {
 | 
			
		||||
  display: inline;
 | 
			
		||||
  font-size: 0.9em;
 | 
			
		||||
  color: #999;
 | 
			
		||||
  margin-left: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
html.js fieldset.collapsed legend a {
 | 
			
		||||
  background-image: url(../../misc/menu-collapsed.png); /* LTR */
 | 
			
		||||
  background-position: 5px 50%; /* LTR */
 | 
			
		||||
| 
						 | 
				
			
			@ -339,9 +347,6 @@ html.js fieldset.collapsed legend a {
 | 
			
		|||
html.js fieldset.collapsible {
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
html.js fieldset.collapsible legend a {
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
/* Avoid jumping around due to margins collapsing into collapsible fieldset border */
 | 
			
		||||
html.js fieldset.collapsible .fieldset-wrapper {
 | 
			
		||||
  overflow: auto;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -381,6 +381,7 @@ function system_elements() {
 | 
			
		|||
    '#theme' => 'file',
 | 
			
		||||
    '#theme_wrapper' => 'form_element',
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $type['tableselect'] = array(
 | 
			
		||||
    '#input' => TRUE,
 | 
			
		||||
    '#js_select' => TRUE,
 | 
			
		||||
| 
						 | 
				
			
			@ -419,10 +420,17 @@ function system_elements() {
 | 
			
		|||
    '#collapsible' => FALSE,
 | 
			
		||||
    '#collapsed' => FALSE,
 | 
			
		||||
    '#value' => NULL,
 | 
			
		||||
    '#process' => array('form_process_ahah'),
 | 
			
		||||
    '#process' => array('form_process_fieldset', 'form_process_ahah'),
 | 
			
		||||
    '#pre_render' => array('form_pre_render_fieldset'),
 | 
			
		||||
    '#theme_wrapper' => 'fieldset',
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $type['vertical_tabs'] = array(
 | 
			
		||||
    '#theme_wrapper' => 'vertical_tabs',
 | 
			
		||||
    '#default_tab' => '',
 | 
			
		||||
    '#process' => array('form_process_vertical_tabs'),
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  $type['token'] = array(
 | 
			
		||||
    '#input' => TRUE,
 | 
			
		||||
    '#theme' => array('hidden'),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,14 @@
 | 
			
		|||
// $Id$
 | 
			
		||||
 | 
			
		||||
(function($) {
 | 
			
		||||
 | 
			
		||||
Drupal.behaviors.bookFieldsetSummaries = {
 | 
			
		||||
  attach: function(context) {
 | 
			
		||||
    $('fieldset#edit-attachments', context).setSummary(function(context) {
 | 
			
		||||
      var size = $('#upload-attachments tbody tr').size();
 | 
			
		||||
      return Drupal.formatPlural(size, '1 attachment', '@count attachments');
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
})(jQuery);
 | 
			
		||||
| 
						 | 
				
			
			@ -231,9 +231,9 @@ function upload_form_alter(&$form, $form_state, $form_id) {
 | 
			
		|||
        '#title' => t('File attachments'),
 | 
			
		||||
        '#collapsible' => TRUE,
 | 
			
		||||
        '#collapsed' => empty($node->files),
 | 
			
		||||
        '#group' => 'additional_settings',
 | 
			
		||||
        '#attached_js' => array(drupal_get_path('module', 'upload') . '/upload.js'),
 | 
			
		||||
        '#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.'),
 | 
			
		||||
        '#prefix' => '<div class="attachments">',
 | 
			
		||||
        '#suffix' => '</div>',
 | 
			
		||||
        '#weight' => 30,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,10 @@ fieldset {
 | 
			
		|||
  background: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs ul.vertical-tabs-list li.first {
 | 
			
		||||
  background-image: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ul.primary {
 | 
			
		||||
  /* Fix missing top margin */
 | 
			
		||||
  position: relative; /* LTR */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -198,6 +198,14 @@ html.js fieldset.collapsed legend a {
 | 
			
		|||
  background: url("images/menu-collapsed-rtl.gif") no-repeat 100% 50%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Vertical tabs.
 | 
			
		||||
 */
 | 
			
		||||
div.vertical-tabs {
 | 
			
		||||
  margin-left: 5%;
 | 
			
		||||
  margin-right: 15em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Syndication Block
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -232,7 +232,7 @@ span.form-required {
 | 
			
		|||
  color: #ffae00;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
span.submitted, .description {
 | 
			
		||||
span.submitted, .description, .vertical-tab-button .summary {
 | 
			
		||||
  font-size: 0.92em;
 | 
			
		||||
  color: #898989;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -829,6 +829,12 @@ fieldset {
 | 
			
		|||
  background-position: 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Keep the background position at 0 for filters and vertical tabs. */
 | 
			
		||||
*:first-child+html fieldset.filter-wrapper,
 | 
			
		||||
*:first-child+html fieldset.vertical-tabs-pane {
 | 
			
		||||
  background-position: 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
*:first-child+html fieldset > .description, *:first-child+html fieldset .fieldset-wrapper .description {
 | 
			
		||||
  padding-top: 1em;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -853,10 +859,47 @@ html.js fieldset.collapsible legend a {
 | 
			
		|||
  background: url(images/menu-expanded.gif) no-repeat 0% 50%; /* LTR */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html.js fieldset.collapsible legend span.summary {
 | 
			
		||||
  color: #898989;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html.js fieldset.collapsed legend a {
 | 
			
		||||
  background: url(images/menu-collapsed.gif) no-repeat 0% 50%; /* LTR */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Vertical tabs.
 | 
			
		||||
 */
 | 
			
		||||
div.vertical-tabs {
 | 
			
		||||
  margin-right: 5%;
 | 
			
		||||
  border-color: #d9eaf5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs .vertical-tabs-panes fieldset.vertical-tabs-pane {
 | 
			
		||||
  padding: 0.5em 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs ul.vertical-tabs-list {
 | 
			
		||||
  border-color: #d9eaf5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs ul.vertical-tabs-list li {
 | 
			
		||||
  background-color: #edf5fa;
 | 
			
		||||
  border-color: #d9eaf5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs ul.vertical-tabs-list li.selected {
 | 
			
		||||
  background: #fff repeat-x 0 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs ul.vertical-tabs-list li.selected.first {
 | 
			
		||||
  background-image: url(images/gradient-inner.png);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.vertical-tabs ul.vertical-tabs-list li.selected a .title {
 | 
			
		||||
  color: #494949;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Syndication icons and block
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue