web-dev-qa-db-fra.com

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

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>

Je dois changer/ajouter des classes CSS dans le <div> OR ajouter un wrapper <div> Externe. Comment faire?

7
volocuga

Si vous définissez vous-même le formulaire, vous pouvez envelopper un élément avec du HTML en utilisant les propriétés #prefix et #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 propriété #attributes :

$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 méthode hook_form_alter(), vous devez ajouter au tableau de classes existant afin de ne pas remplacer les classes qui ont été définies précédemment.

9
Clive

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 , pour utiliser #after_build pour pouvoir modifier les radios individuelles de l'élément de formulaire une fois qu'elles sont un tableau de rendu drupal.

Je voulais que chaque radio soit enveloppée dans un conteneur avec une classe, alors j'ai utilisé #prefix et #suffix pour faire ça:

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'élément input ait la classe dont vous avez besoin pour implémenter la solution que j'ai publiée sur drupal.org à https://api.drupal.org/comment/60197#comment -60197 pour permettre aux #options_attributes d'être utilisées 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'
        )
    )
 );
1
DrCord

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>'
);
1
Strutsagget

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.

0
Visualise