adicionar / alterar wrapper div em torno de um botão de opção específico?

7

Por padrão, a marcação HTML para botões de opção é semelhante a (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>

Eu preciso alterar / adicionar algumas classes css no exterior <div>ou adicionar um wrapper <div>. Como faço isso?

volocuga
fonte
11
Você já descobriu como fazer isso?
Dominic
você achou que a resposta realmente era a mesma que procurava resposta para esses atributos de invólucro em mudança ao redor de cada botão de opção .. por favor responda .. obrigado
Gostaria de saber se você pode esclarecer de onde vem o -SOME_ID no seu tema "por padrão" Drupal de rádios. Para nivelar as variáveis, mudei para Sete tema e ainda ver apenas o ID do grupo de rádios, não um invólucro em cada item :(
texas-Bronius

Respostas:

9

Se você mesmo estiver definindo o formulário, poderá agrupar um elemento com HTML usando as propriedades #prefixe #suffix:

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

Se você deseja adicionar uma classe ao wrapper existente, pode fazê-lo usando a #attributespropriedade:

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

Se você não estiver definindo o formulário, ainda poderá usar a mesma lógica e implementar a hook_form_alter()para alterar o formulário existente:

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

Observe que, ao usar o hook_form_alter()método, você deve anexar à matriz de classes existente para não substituir nenhuma classe que foi definida anteriormente.

Clive
fonte
6
I invólucro média em torno de cada botão de rádio, não grupo
volocuga
11
Isso é feito para todo o grupo de rádios e não para os botões de opção individuais.
DrCord
1

Você pode fazer o acima (prefixo / sufixo) nos itens da matriz de opções e obter o que quiser em torno de cada item.

$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
fonte
11
Eu quero acreditar, mas isso não está fazendo por mim (D7). Em vez disso, apenas preenche o prefixo + sufixo como um elemento irmão imediatamente anterior aos elementos de opções agrupados individualmente por div. Poderia ser um erro de digitação, e realmente existe um caminho?
texas-Bronius
Parece que você está adicionando o div a uma opção inexistente. Pense que você precisa garantir que os valores da matriz de opções sejam iguais.
Strutsagget
Isso definitivamente faz o que o texas-bronius diz, adiciona um elemento separado no mesmo nível dos botões de opção, e não uma solução funcional, infelizmente.
DrCord
1

Consegui isso depois de muito trabalho e tentando todos os métodos publicados usando uma dica inteligente que encontrei no fundo da internet em outro site: http://e9p.net/altering-individual-radio-or-checkbox-items-drupal- 7-fapi , para #after_buildpoder alterar os rádios individuais do elemento de formulário, uma vez que eles são uma matriz de renderização drupal.

Eu queria que cada rádio fosse embrulhado em um contêiner com uma classe, então usei #prefixe #suffixfiz isso:

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

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

No entanto, se você deseja que apenas o inputelemento tenha a classe, precisará implementar a solução que eu publiquei no drupal.org em https://api.drupal.org/comment/60197#comment-60197 para permitir que os #options_attributes sejam usados corretamente para opções individuais. Postando novamente o código aqui:

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

exemplo 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
fonte
0

A única maneira de conseguir isso é criando um elemento de formulário diferente para cada rádio, associando manualmente os nomes usando #name e definindo manualmente um valor usando #attributes. (#value não funciona por algum motivo.)

Por exemplo:

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

Isso adicionará um invólucro e uma classe aos botões de opção individuais, em vez do grupo de opções, como a resposta atualmente aceita.

Visualizar
fonte