Pass radio element arrays through options in radios element

Created on 30 December 2021, almost 3 years ago
Updated 3 April 2024, 9 months ago

Problem/Motivation

You somethings want some individual controle on attributes on single radio elements, especially with css and js interaction on the frontend. Using radios complicates this, and needs you to do all kinds of preprocessing around it instead of passing a radio item render array using the render array definition for radios.

Currently you can only do this:

 $form['settings']['active'] = array(
   '#type' => 'radios',
   '#title' => $this->t('Poll status'),
   '#default_value' => 1,
   '#options' => array(0 => $this->t('Closed'), 1 => $this->t('Active')), #<--
 );

While the single radio button generated within the "radios" element can have more attributes. But there is no way to pass that along currently in the radios element.

This is the processRadios function from Drupal\Core\Render\Element\Radios

     foreach ($element['#options'] as $key => $choice) {

        #... some stuff ...

        $element[$key] += [
          '#type' => 'radio',
          '#title' => $choice,
          // The key is sanitized in Drupal\Core\Template\Attribute 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' => HtmlUtility::getUniqueId('edit-' . implode('-', $parents_for_id)),
          '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
          // Errors should only be shown on the parent radios element.
          '#error_no_message' => TRUE,
          '#weight' => $weight,
        ];

You can only pass a $key $value ($choice) array along which should be int/strings. So no way to pass along unique attributes per radio items in radios.

Proposed resolution

Why not also allow do something like this:

        $singleRadio = [
          '#type' => 'radio',
          // The key is sanitized in Drupal\Core\Template\Attribute 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' => HtmlUtility::getUniqueId('edit-' . implode('-', $parents_for_id)),
          '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
          // Errors should only be shown on the parent radios element.
          '#error_no_message' => TRUE,
          '#weight' => $weight,
        ];

        if (is_array($choice)) {
          $singleRadio = NestedArray:mergeDeep($singleRadio, $choice);
        }

        $singleRadio['#return_value'] = $key;
        $element[$key] += $singleRadio;

That way we can allow the normal and more advanced method in a single element.

  $form['settings']['active'] = array(
    '#type' => 'advanced_radios',
    '#title' => $this->t('Poll status'),
    '#default_value' => 1,
    '#options' => array(0 => ['#title' => $this->t('Closed'), '#attributes' => ['data-something' => 'example'], 1 => $this->t('Active')),
  );
✨ Feature request
Status

Closed: works as designed

Version

9.4

Component
RenderΒ  β†’

Last updated about 8 hours ago

Created by

πŸ‡³πŸ‡±Netherlands jefuri

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.

  • πŸ‡ΊπŸ‡ΈUnited States reuven

    Add custom class to every radio's elements
    Show radio element inline

    $radioOptions = [
    'red'=>'Red',
    'blue'=>'Blue',
    'white'=>'White',
    'black'=>'Black',
    'orange'=>'Orange',
    ];
    $form['custom_radios'] = [
    '#type' => 'radios',
      // ...
      '#options' => $radioOptions,
    ];
    
    foreach($radioOptions as $key=>$value) {
              $form['custom_radios'][$key] =  [
                  '#wrapper_attributes' => [
                      'class' => [
                          'form-check-inline',
                          'custom_class'
                      ],
                  ],
              ];
          }
    
    
Production build 0.71.5 2024