I need to modify the html code of radio buttons generated by Ubercart Attributes. So I want to do it using hook_form_alter().

enter image description here

If I dsm() the $form I need to change using hook_form_alter() I get this

attributes (Array, 7 elements)
#theme (String, 24 characters ) uc_attribute_add_to_cart
#id (String, 42 characters ) uc_product_add_to_cart_form-472-attributes
    #type (String, 6 characters ) radios
    #default_value (NULL)
    #options (Array, 4 elements)
        0 (String, 7 characters ) Color 1
        1 (String, 7 characters ) Color 2
        2 (String, 7 characters ) Color 3
        3 (String, 8 characters ) Color 17
    #ajax (Array, 2 elements)
    #title (String, 4 characters ) yeah
    #description (String, 0 characters )
    #required (String, 1 characters ) 1

I can apply a #prefix/#suffix to div wrapping all radio buttons:

<div class="test">
  <div class="form-item form-type-radios form-item-attributes-8">
     <div class="form-label">
        <div class="element-inner">
           <div class="el">
               <div id="edit-attributes-8" class="form-radios my-custom-class">
               <div class="form-item form-type-radio form-item-attributes-8">
               <div class="form-item form-type-radio form-item-attributes-8">
               <div class="form-item form-type-radio form-item-attributes-8">
              <div class="form-item form-type-radio form-item-attributes-8">
        <div class="description"></div>

I proceed like that for this result:

$form['attributes']['8']['#prefix'] = '<div class="test">';
$form['attributes']['8']['#suffix']= '</div>'; 

The problem is that I want to apply this #prefix/#suffix to all options instead, I tried something like that but it doesn't work:

$form['attributes']['8']['#options'][0]['#prefix'] = '<div class="test">';
$form['attributes']['8']['#options'][0]['#suffix']= '</div>'; 

So is it possible to do it this way? Any suggestion?

4 Answers 4


In your form_alter you can tell drupal to use your custom theme_radio like this:

$form['attributes']['#theme'] = 'MYCUSTOM_radio_theme';

Then in 'MYCUSTOM_radio_theme:

$element = $variables['element'];

$element['#attributes']['type'] = 'radio';

element_set_attributes($element, array('id', 'name','#return_value' => 'value'));

if (isset($element['#return_value']) && $element['#value'] !== FALSE && $element['#value'] == $element['#return_value']) {
    $element['#attributes']['checked'] = 'checked';

  _form_set_class($element, array('form-radio'));

  return '<div class="test"><input' . drupal_attributes($element['#attributes']) . ' /></div>';
  • Thanks for this information. Unfortunately I was not able to do it this way. I was just able to call theme_radio() from my template.php file using this name: mytheme_radio(). Is it possible to call 'MYCUSTOM_radio_theme' from .module file? How??
    – 118218
    Commented Oct 6, 2014 at 14:12
  • you need to register your theme function with hook_theme
    – 2pha
    Commented Oct 7, 2014 at 3:40
  • @2pha, can you give more info about how to register a theme function in .module files? I tried something like declaring two functions: MY_MODULE_theme($existing, $type, $theme, $path) and theme_custom_radio().
    – 118218
    Commented Oct 8, 2014 at 12:00
  • 1
    I think this page will help you to understand how to write your hook_theme: hook_theme
    – Akko
    Commented Oct 8, 2014 at 14:48

There is an easy answer to this, but I was very nearly driven insane trying to find it because it doesn't appear to be documented anywhere.

$form['input']['option_key'] = array(
  '#prefix' => '',
  '#suffix' => '',

This is counter-intuitive because it creates an entirely new array for #prefix and #suffix, but I swear it works. In OP's case you would use $form['attributes'][0] to get the first option ('attributes' appears to be the name of the radio button collection, not the form's #attributes array). If it were using strings as array keys you'd use $form['attributes']['option_name'].

I imagine you can do some other interesting things too.

  • This is awesome, and should be the answer!
    – Collins
    Commented Feb 9, 2017 at 12:24
  • oops, i got ahead of myself. This doesnt work for checkbox options, as you cannot set a #value or #title for the label, and so the ley > label relationship does not work.
    – Collins
    Commented Feb 9, 2017 at 12:33

Maybe you could override the theme_radio function instead of using form_alter.


Since I can't comment, what @taburk has said is by far the best option. A note of point though, this method can ONLY be done with a hook_form_alter (or hook_form_FORM_ID_alter) as the form array must already exist.

Also, in your form alter remember that as the array already exists you need to append the prefix/suffix keys to it, not overwrite the existing array.

if($form_id == 'my_form_id'){
        foreach($form['my_radio_field']['#options'] as $macname => $thememarkup) {
            $form['my_radio_field'][$macname]['#prefix'] = '<div class="col-md-6">';
            $form['my_radio_field'][$macname]['#suffix'] = '</div>';

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.