agregar / cambiar envoltorio div alrededor del botón de radio específico?

7

De forma predeterminada, el marcado HTML para botones de radio se ve así (Drupal 7):

<div class="form-item form-type-radio form-item-SOME_ID">
  <input id="edit-SOME_ID" class="form-radio" type="radio" value="SOME_VALUE" name="SOME_NAME" /> 
  <label class="option" for="edit-bla-bla">MY LABEL</label>
</div>

Necesito cambiar / agregar algunas clases de CSS en el exterior <div>O agregar un contenedor <div>. ¿Cómo puedo hacer eso?

volocuga
fuente
1
¿Alguna vez descubriste cómo hacer esto?
Dominic
¿Encontró que la respuesta en realidad era la misma? Buscando la respuesta para este cambio de atributos de envoltura alrededor de cada botón de radio ... por favor responda ... gracias
Me pregunto si podría aclarar de dónde proviene el -SOME_ID en su tema "por defecto" Drupal de radios. Para nivelar las variables, cambié al tema Siete y todavía veo solo la ID del grupo de radios, no un contenedor en cada elemento :(
texas-bronius

Respuestas:

9

Si está definiendo el formulario usted mismo, puede ajustar un elemento con HTML utilizando las propiedades #prefixy #suffix:

$form['radios'] = array(
  '#type' => 'radios',
  '#title' => 'Options',
  '#options' => drupal_map_assoc(1, 2, 3),
  '#prefix' => '<div class="some-class">',
  '#suffix' => '</div>'
);

Si desea agregar una clase al contenedor existente, puede hacerlo utilizando la #attributespropiedad:

$form['radios'] = array(
  '#type' => 'radios',
  '#title' => 'Options',
  '#options' => drupal_map_assoc(1, 2, 3),
  '#attributes' => array(
    'class' => array('some-class')
  )
);

Si no está definiendo el formulario usted mismo, puede usar la misma lógica e implementar a hook_form_alter()para cambiar el formulario existente:

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'some_form_id') {
    $form['some_element']['#attributes']['class'][] = 'some-class';
  }
}

Tenga en cuenta que cuando utilice el hook_form_alter()método, debe agregarlo a la matriz de clases existente para no anular ninguna clase que se haya configurado previamente.

Clive
fuente
66
Me refiero a envolver alrededor de cada botón de radio, no en grupo
volocuga
1
Esto lo hace para todo el grupo de radios, no para los botones de radio individuales.
DrCord
1

Puede hacer lo anterior (prefijo / sufijo) en los elementos de la matriz de opciones y luego obtendrá lo que desee alrededor de cada elemento.

$form['view_mode'] = array(
    '#type' => 'radios',
    '#default_value' => isset($_GET['view'])?$_GET['view']:1,
    '#options' => array(
          1 => '1',
          2 => '2',
          3 => '3',
    ),
  ),
);
$form['view_mode'][1] = array(
    '#prefix' => '<div class="first-item container">',
    '#suffix' => '</div>'
);
Strutsagget
fuente
1
Quiero creer, pero esto no lo está haciendo por mí (D7). En cambio, solo se introduce en el prefijo + sufijo como un elemento hermano que precede inmediatamente a los elementos de opciones individualmente divididos. ¿Podría ser un error tipográfico, y realmente hay una manera?
texas-bronius
Suena como si estuvieras agregando el div a una opción que no existe. Cree que debe asegurarse de que los valores de la matriz de opciones coincidan entre sí.
Strutsagget
Esto definitivamente hace lo que dice texas-bronius, agrega un elemento separado al mismo nivel que los botones de radio, lamentablemente no es una solución que funcione.
DrCord
1

Pude lograr esto después de mucho trabajo y probando cada método publicado usando un consejo inteligente que encontré en Internet en otro sitio: http://e9p.net/altering-individual-radio-or-checkbox-items-drupal- 7-fapi , para #after_buildpoder modificar las radios individuales del elemento de forma una vez que son una matriz de renderizado de drupal.

Quería cada radio envuelta en un contenedor con una clase, así que usé #prefixy #suffixpara hacer eso:

function _MYMODULE_options_after_build(&$element, &$form_state){
    // Each renderable radio element.
    foreach (element_children($element) as $key) {
        $element[$key]['#prefix'] = '<div class="class1 class2">';
        $element[$key]['#suffix'] = '</div>';
    }
    // Always return the element to render in after_build callbacks.
    return $element;
}

ejemplo de uso:

$form['style'] = array(
        '#type' => 'radios',
        '#title' => t('Select your style option'),
        '#options' => $style_options,
        '#default_value' => NULL,
        '#required' => TRUE,
        '#after_build' => array(
            '_MYMODULE_options_after_build'
        )
);

Sin embargo, si solo desea que el inputelemento tenga la clase, deberá implementar la solución que publiqué en drupal.org en https://api.drupal.org/comment/60197#comment-60197 para permitir que se usen los #options_attributes correctamente para opciones individuales. Volver a publicar el código aquí:

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;
}

ejemplo de uso:

$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'
        )
    )
 );
DrCord
fuente
0

La única forma en que he podido lograr esto es creando un elemento de formulario diferente para cada radio, emparejando manualmente los nombres usando #name y estableciendo manualmente un valor usando #attributes. (#value no funciona por alguna razón).

Por ejemplo:

$form['apple'] = array(
  '#type' => 'radio', // Notice no s here; 'radio' not 'radios'
  '#name' => 'fruit', // This will ensure the radios are in the same group
  '#attributes' => array(
       'value' => 'apple', // I know this is bad but it's the only way I could get setting a value to work
       'class' => 'class_here' // This will add class_here to the default wrapper
   ),
  '#prefix' => '<div class="some-class">', // This will prefix the individual radio, wrapper and label
  '#suffix' => '</div>' // This will suffix the individual radio, wrapper and label
);

// Then just repeat with different values

$form['orange'] = array(
  '#type' => 'radio',
  '#name' => 'fruit', // Same name
  '#attributes' => array(
       'value' => 'orange', // Different value
       'class' => 'class_here'
   ),
  '#prefix' => '<div class="some-class">',
  '#suffix' => '</div>'
);

$form['banana'] = array(
  '#type' => 'radio',
  '#name' => 'fruit', // Same name
  '#attributes' => array(
       'value' => 'banana', // Different value
       'class' => 'class_here'
   ),
  '#prefix' => '<div class="some-class">',
  '#suffix' => '</div>'
);

Esto agregará un contenedor y una clase a los botones de radio individuales en lugar del grupo de radio como lo hace la respuesta actualmente aceptada.

Visualizar
fuente