form_process_vertical_tabs have to have #weight value set

Created on 2 January 2012, over 12 years ago
Updated 20 July 2023, about 1 year ago

I'm writing a JS for vertical tabs so when some element fails on validation the tab(li element) gets 'error' class. I was struggling with a bug where some tabs would get the class properly and others would be skipped and next tab woud get the error class instead.

This was due to missing '#weight' value in form_process_vertical_tabs. I have set weights to my tabs and they have values from -10 to 8. So one of my tabs gets #weight => 0. This is the tab that splits the tabs that are working correctly with my JS and tabs that are not working correctly. The reason is because the __active tab input is put behind my tab with weight => 0 so indexes(position of fieldset) won't match tab li element index(position in ul).

So to fix this there needs to be weight parameter set in form_process_vertical_tabs which will place the __active tab element at the end of the form.

function form_process_vertical_tabs($element, &$form_state) {
  // Inject a new fieldset as child, so that form_process_fieldset() processes
  // this fieldset like any other fieldset.
  $element['group'] = array(
    '#type' => 'fieldset',
    '#theme_wrappers' => array(),
    '#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' => array('vertical-tabs-active-tab'))
  );

  return $element;
}
function form_process_vertical_tabs($element, &$form_state) {
  // Inject a new fieldset as child, so that form_process_fieldset() processes
  // this fieldset like any other fieldset.
  $element['group'] = array(
    '#type' => 'fieldset',
    '#theme_wrappers' => array(),
    '#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' => array('vertical-tabs-active-tab')),
    '#weight' => 1000
  );

  return $element;
}

This is my script so you can see what I'm talking about:

$('div.vertical-tabs-panes > fieldset').has('.error').each(function(i) {
  $('ul.vertical-tabs-list > li').eq($(this).index()).addClass('error');
});
πŸ“Œ Task
Status

Closed: outdated

Version

9.5

Component
FormΒ  β†’

Last updated less than a minute ago

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024