6

I need to style my radios as tabs. So I created a form element like this:

$form['important_categories'] = array (
  '#type' => 'radios',
  '#label' => NULL,
  '#attributes' => array (
    'class' => array (
      'radioTabs',
    ),
  ),
);

foreach ($important_categories as $id_important_category => $important_category_name) {
  $form['important_categories']['#options'][$id_important_category] = $important_category_name;
  if(!isset($form['important_categories']['#default_value'])) {
    $form['important_categories']['#default_value'] = $id_important_category;
  }
}

This properly sets options, and sets first element as default. However, it add classes in two places. Here I wanted it:

<div id="edit-important-categories" class="form-radios radioTabs">

Here I didn't:

<input id="edit-important-categories-22" class="radioTabs form-radio" type="radio" value="22" name="important_categories">

On individual radio, I need radioTab (singular, not plural), and on default one also radioTabDefault.

Is there any built-in method to get this? Or do I need to alter my theme, like I did for labels? If so, what function I should modify?

1
  • I know about this request and solution, but it changes core function, and I failed to figure out how to do it at module or theme level instead.
    – Mołot
    Commented Aug 26, 2014 at 8:19

2 Answers 2

8

No there's nothing built-in for this (take a look at form_process_radios(), nothing in there that would let you specify individual classes).

No need to hack core though like in the solution you linked to. Simply implement hook_element_info_alter(), and replace the process function with your own, which will be based on the original form_process_radios(), but that can handle individual classes for options.

function MYMODULE_element_info_alter(&$info) {
  // You might want more advanced logic here, to replace instead of override altogether,
  // in case other modules have already altered the core info.
  $info['radios']['#process'] = array('MYMODULE_process_radios');
}

function MYMODULE_process_radios($element) {
  // ...
  return $element;
}
2
  • Thanks. I usually stay far away from front-end, so I'm not as fluent with it as I would like to be. But this worked pretty OK.
    – Mołot
    Commented Aug 26, 2014 at 9:07
  • 1
    Yeah it still does feel a bit awkward but I'm not sure there's a simpler way
    – Clive
    Commented Aug 26, 2014 at 9:07
5

This is solution for Drupal 8.

Read the Forms API documentation on the '#after_build' form element property.

In Form Controller file - Radio button use '#after_build':

$form['myoptions'] = [
  '#type' => 'radios',
  '#title' => t('My Options'),
  '#after_build' => array('custom_process_radios'),
//  ..
];

In your .module file code - defining the custom function.

/**
 * Processing Radios Element using #after_build property.
 * Adding the class attribute for individual radio button.
 * @element  array
 * @form_state  array
 * @return array
 */
function custom_process_radios($element, $form_state) {
  $options = array_keys($element['#options']);
  foreach($options as $values) {
    $element[$values]['#attributes']['class'][] = 'myclass';
  }
  return $element;
}

Read purpose of all the properties for Form Element

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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