0

I am trying to override the theme_fieldset function in a custom node edit form where the fieldset is added dynamically.

Here is what my code looks like:

function cms_content_edit(){
  $node = node_load(3089);
  module_load_include('inc', 'node', 'node.pages');
  $form = drupal_get_form('test_node_form', $node);
  $form['block1'] = array(
    '#type' => 'fieldset',
    '#title' => t('Block 1'),
    '#weight' => -50,
    '#collapsible' => true,
    '#collapsed' => true,
    '#attributes' => array('class' => array('portlet box blue-hoki')),
    '#theme' => 'fieldset_custom3',
  );
  $form['block1']['title'] = $form['title'];
  unset($form['title']);
  $form['block1']['body'] = $form['body'];
  unset($form['body']);
  $form['block1']['field_fichier'] = $form['field_fichier'];
  unset($form['field_fichier']);
  $output = drupal_render($form);
  return $output;
}

The custom function is defined this way in my .module file:

function theme_fieldset_custom3($variables) {
  $element = $variables['element'];
  element_set_attributes($element, array('id'));
  _form_set_class($element, array('form-wrapper'));

  $output = '<fieldset' . drupal_attributes($element['#attributes']) . '>';
  if (!empty($element['#title'])) {
    // Always wrap fieldset legends in a SPAN for CSS positioning.
    $output .= '<div class="portlet-title">' . $element['#title'] . '</div>';
  }
  $output .= '<div class="fieldset-wrapper">';
  if (!empty($element['#description'])) {
    $output .= '<div class="fieldset-description">' . $element['#description'] . '</div>';
  }
  $output .= $element['#children'];
  if (isset($element['#value'])) {
    $output .= $element['#value'];
  }
  $output .= '</div>';
  $output .= "</fieldset>\n";
  return $output;
}

Unfortunately my custom function is not called at all.

Did I do something wrong?

******** EDIT *********

Thanks to @kiamlaluno, after I added my custom function to hook_theme(), my custom function was actually loaded.

function mymodule_theme() {
  return array(
    'fieldset_custom3' => array(
      'render element' => 'element',
    ),
  );
}

The problem now is that the .fieldset-wrapper div is empty. In my custom function, the $element['#children'] array is empty...

My fieldset is created dynamically, like that (in hook_form_alter()):

if(isset($form['#node_edit_form']) && $form['#node_edit_form']==TRUE && $form['nid']['#value']!=''){

       $form['block1'] = array(
          '#type' => 'fieldset',
          '#title' => t('Block 1'),
          '#weight' => -50,
          '#collapsible' => false,
          '#collapsed' => false,
        );
        $form['block1']['title'] = $form['title'];
        unset($form['title']);
        $form['block1']['body'] = $form['body'];
        unset($form['body']);
        $form['block1']['field_fichier'] = $form['field_fichier'];
        unset($form['field_fichier']);
        $form['block1']['#theme'] = 'fieldset_custom3';
        // $form['actions']['submit']['#submit']['0'] = 'node_form_submit_custom';
    }

I also tried this way (this is a custom page):

function cms_content_edit(){
  $node = node_load(3089);
  module_load_include('inc', 'node', 'node.pages');
  $form = drupal_get_form('test_node_form', $node);
  $form['block1'] = array(
    '#type' => 'fieldset',
    '#title' => t('Block 1'),
    '#weight' => -50,
    '#collapsible' => true,
    '#collapsed' => true,
    '#attributes' => array('class' => array('portlet box blue-hoki')),
    '#theme' => 'fieldset_custom3',
  );
  $form['block1']['title'] = $form['title'];
  unset($form['title']);
  $form['block1']['body'] = $form['body'];
  unset($form['body']);
  $form['block1']['field_fichier'] = $form['field_fichier'];
  unset($form['field_fichier']);
  $output = drupal_render($form);
  return $output;
}

But the problem is the same.

******** EDIT 2 *********

I also noticed that the issue also happens when I try to use the default theme_fieldset() function as configuration:

$block1 = array(
        '#type' => 'fieldset',
        '#title' => t('Block 1'),
        '#weight' => -50,
        '#collapsible' => true,
        '#collapsed' => false,
        '#description' => t('Edit the welcome e-mail messages sent to new member accounts created by an administrator.'),
        '#tree' => TRUE,
        '#theme' => 'fieldset',
      );
      $form['block1'] = $block1;
      $form['block1']['body'] = $form['body'];

I double checked and the theme_fieldset() function (/includes/form.inc) is actually well called, but the fieldset is not generated as expected. Apparently something is missing so Drupal can do the job. May be the $variables object.

Here is a screenshot of what my form looks like with this configuration.

enter image description here

When I don't use the "#theme" config, everything is perfect:

$block1 = array(
    '#type' => 'fieldset',
    '#title' => t('Block 1'),
    '#weight' => -50,
    '#collapsible' => true,
    '#collapsed' => false,
    '#description' => t('Edit the welcome e-mail messages sent to new member accounts created by an administrator.'),
    '#tree' => TRUE,
  );
  $form['block1'] = $block1;
  $form['block1']['body'] = $form['body'];

enter image description here

  • If you want to create custom field groups, maybe better to refer to a module like: drupal.org/project/field_group for examples and alternative implementations. – David Thomas Jun 15 '16 at 0:21
  • As side note, you aren't overriding theme_fieldset(): You are using a different theme function. – kiamlaluno Jun 15 '16 at 3:38
  • Thank you @DavidThomas, I know this module. But I want to add this feature to my own module and avoid third party modules. – 118218 Jun 15 '16 at 8:54
  • 1
    I think that @DavidThomas was suggesting to look at what that module does to achieve its purpose; maybe it can help you to understand what code you should use. – kiamlaluno Jun 15 '16 at 9:02
1

You cannot use a theme function if you don't make Drupal know about it first. To do that, you need to implement hook_theme().

function mymodule_theme() {
  return array(
    'fieldset_custom3' => array(
      'render element' => 'element',
    ),
  );
}
  • Thank you @kiamlaluno, indeed with this implementation, my custom function is called as expected. The problem now is that the .fieldset-wrapper div is empty. In my function, the $element['#children'] array is empty... My fieldset is created dynamically, may be this point is causing the issue. – 118218 Jun 15 '16 at 8:30
  • That should not make any difference, since the code you are using is the same Drupal uses. The only difference I see is that you set both #type and #theme, but that should not be a problem either. – kiamlaluno Jun 15 '16 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.