ajouter / modifier le wrapper div autour d'un bouton radio spécifique?

7

Par défaut, le balisage HTML des boutons radio ressemble à (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>

J'ai besoin de changer / ajouter des classes CSS dans l'extérieur <div>OU ajouter un wrapper <div>. Comment je fais ça?

volocuga
la source
1
Avez-vous déjà compris comment procéder?
Dominic
avez-vous trouvé que la réponse était en fait la même que la recherche de réponse pour ce changement d'attributs d'encapsuleur autour de chaque bouton radio .. veuillez répondre .. merci
Je me demande si vous pourriez clarifier d'où vient le -SOME_ID dans votre thème Drupal "par défaut" des radios. Pour niveler les variables, je suis passé au thème Seven et je ne vois toujours que l'ID du groupe de radios, pas un wrapper sur chaque élément :(
texas-bronius

Réponses:

9

Si vous définissez vous-même le formulaire, vous pouvez envelopper un élément avec du HTML à l'aide des propriétés #prefixet #suffix:

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

Si vous souhaitez ajouter une classe à l'encapsuleur existant, vous pouvez le faire en utilisant la #attributespropriété:

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

Si vous ne définissez pas le formulaire vous-même, vous pouvez toujours utiliser la même logique et implémenter un hook_form_alter()pour modifier le formulaire existant:

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

Notez que lorsque vous utilisez la hook_form_alter()méthode, vous devez ajouter au tableau de classes existant afin de ne pas remplacer les classes qui ont été définies précédemment.

Clive
la source
6
Je veux dire enrouler autour de chaque bouton radio, pas groupe
volocuga
1
Cela le fait pour l'ensemble du groupe de radios et non pour les boutons radio individuels.
DrCord
1

Vous pouvez faire ce qui précède (préfixe / suffixe) sur les éléments du tableau d'options, puis vous obtenez tout ce que vous voulez autour de chaque élément.

$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
la source
1
Je veux croire, mais cela ne le fait pas pour moi (D7). Au lieu de cela, il place simplement le préfixe + suffixe comme un élément frère précédant immédiatement les éléments d'options enveloppés individuellement. Serait-ce une faute de frappe, et il y a vraiment un moyen?
texas-bronius
Sonne comme si vous ajoutiez le div à une option inexistante. Pensez que vous devez vous assurer que les valeurs du tableau d'options correspondent.
Strutsagget
Cela fait définitivement ce que dit texas-bronius, ajoute un élément séparé au même niveau que les boutons radio, pas une solution de travail, malheureusement.
DrCord
1

J'ai pu y parvenir après beaucoup de travail et en essayant chaque méthode publiée en utilisant une astuce intelligente que j'ai trouvée profondément sur Internet sur un autre site: http://e9p.net/altering-individual-radio-or-checkbox-items-drupal- 7 fapi , à utiliser #after_buildpour pouvoir modifier les radios individuelles de l'élément de forme une fois qu'elles sont un tableau de rendu drupal.

Je voulais que chaque radio soit emballée dans un conteneur avec une classe, alors j'ai utilisé #prefixet #suffixpour cela:

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

exemple d'utilisation:

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

Cependant, si vous souhaitez uniquement que l' inputélément ait la classe, vous devez implémenter la solution que j'ai publiée sur drupal.org à https://api.drupal.org/comment/60197#comment-60197 pour autoriser l'utilisation des #options_attributes correctement pour les options individuelles. Code de re-publication ici:

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

exemple d'utilisation:

$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
la source
0

La seule façon dont j'ai pu y parvenir est de créer un élément de formulaire différent pour chaque radio, d'appairer manuellement les noms à l'aide de #name et de définir manuellement une valeur à l'aide de #attributes. (#value ne fonctionne pas pour une raison quelconque.)

Par exemple:

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

Cela ajoutera un wrapper et une classe aux boutons radio individuels plutôt qu'au groupe radio comme le fait la réponse actuellement acceptée.

Visualiser
la source