7.x form.inc form_process_radios($element)

Expands a radios element into individual radio elements.

Related topics

1 string reference to 'form_process_radios'
system_element_info in modules/system/system.module
Implements hook_element_info().

File

includes/form.inc, line 3178
Functions for form and batch generation and processing.

Code

function form_process_radios($element) {
  if (count($element['#options']) > 0) {
    $weight = 0;
    foreach ($element['#options'] as $key => $choice) {
      // Maintain order of options as defined in #options, in case the element
      // defines custom option sub-elements, but does not define all option
      // sub-elements.
      $weight += 0.001;

      $element += array($key => array());
      // Generate the parents as the autogenerator does, so we will have a
      // unique id for each radio button.
      $parents_for_id = array_merge($element['#parents'], array($key));
      $element[$key] += array(
        '#type' => 'radio',
        '#title' => $choice,
        // The key is sanitized in drupal_attributes() during output from the
        // theme function.
        '#return_value' => $key,
        // Use default or FALSE. A value of FALSE means that the radio button is
        // not 'checked'.
        '#default_value' => isset($element['#default_value']) ? $element['#default_value'] : FALSE,
        '#attributes' => $element['#attributes'],
        '#parents' => $element['#parents'],
        '#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
        '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
        '#weight' => $weight,
      );
    }
  }
  return $element;
}

Comments

erlendoos’s picture

This can be done by overriding the theme_radio function :-) It is called before theme_radios, where the result is processed as html in the #children parameter.

Good luck!

erlendoos’s picture

You could also define a new element type by the hook_element_info, borrow the implementation for radios from the system_element_info. In that way you are more on top of the theme implementation from the start.

DrCord’s picture

I was able to do this using the advice above and wanted to share my code to help others.

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('safetycal_request_a_quote_process_radios');
}

function MYMODULE_process_radios($element) {
    // for some reason when I take over processing the radios the structure
    // is slightly different than with form_process_radios and it needs to be fixed
    if(isset($element['element'])){
        $element = $element['element'];
    }
    if (count($element ['#options']) > 0) {
        $weight = 0;
        foreach ($element ['#options'] as $key => $choice) {
            // Maintain order of options as defined in #options, in case the element
            // defines custom option sub-elements, but does not define all option
            // sub-elements.
            $weight += 0.001;

            $element += array($key => array());
            // Generate the parents as the autogenerator does, so we will have a
            // unique id for each radio button.
            $parents_for_id = array_merge($element ['#parents'], array($key));
            $element [$key] += array(
                '#type' => 'radio',
                '#title' => $choice,
                // The key is sanitized in drupal_attributes() during output from the
                // theme function.
                '#return_value' => $key,
                // Use default or FALSE. A value of FALSE means that the radio button is
                // not 'checked'.
                '#default_value' => isset($element ['#default_value']) ? $element ['#default_value'] : FALSE,
				// changed below line to use the #options_attributes array
                '#attributes' => $element['#option_attributes'][$key],
                '#parents' => $element ['#parents'],
                '#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
                '#ajax' => isset($element ['#ajax']) ? $element ['#ajax'] : NULL,
                '#weight' => $weight,
            );
        }
    }
    return $element;
}

example use:

$style_options = array(
	'red' => 'Red',
	'green' => 'Green',
	'yellow' => 'Yellow'
);
$style_option_attributes = array(
	'red' => array(
		'class' => array(
                'red-class'
            )
	),
	'green' => array(
		'class' => array(
                'green-class'
            )
	),
	'yellow' => array(
		'class' => array(
                'yellow-class'
            )
	)
);
$form['style'] = array(
	'#type' => 'radios',
	'#title' => t('Select your style option'),
	'#options' => $style_options,
	'#option_attributes' => $style_option_attributes,
	'#default_value' => NULL,
	'#required' => TRUE,
	'#attributes' => array(
		'class' => array(
			'radio-element-class'
		)
	)
 );
tmcfarlin4’s picture

To properly override the process function, you should implement the HOOK_element_info_alter function & set the process function. This implementation results in the custom process function being called after the form.inc process function (rather than in place of).

function MODULE_element_info_alter(&$types) {
  if (isset($types['radios']['#process'])) {
    $types['radios']['#process'] = array('MODULE_form_process_radios');
  }
}

You can then do what you want in your MODULE_form_process_radios function (I add an additional property & handle it here).