добавить / изменить упаковщик div вокруг определенной кнопки?

7

По умолчанию разметка HTML для переключателей выглядит следующим образом (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>

Мне нужно изменить / добавить некоторые классы CSS во внешнем <div>ИЛИ добавить обертку <div>. Как я могу это сделать?

volocuga
источник
1
Вы когда-нибудь выясняли, как это сделать?
Доминик
Вы нашли ответ, который на самом деле был тем же самым, ища ответ для этого изменяющегося атрибута обертки вокруг каждой радиокнопки ... ответьте пожалуйста .. спасибо
Интересно, не могли бы вы уточнить, откуда -SOME_ID используется в ваших "по умолчанию" тематике радиостанций в Drupal. Чтобы выровнять переменные, я переключился на тему «Семь» и по-прежнему вижу только идентификатор группы радиостанций, а не обертку для каждого элемента :(
texas-bronius

Ответы:

9

Если вы определяете форму самостоятельно , вы можете заключить элемент с HTML с использованием #prefixи #suffixсвойства:

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

Если вы хотите добавить класс к существующей оболочке, вы можете сделать это, используя #attributesсвойство:

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

Если вы не определяете форму самостоятельно, вы все равно можете использовать ту же логику и реализовать a hook_form_alter()для изменения существующей формы:

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

Обратите внимание, что при использовании hook_form_alter()метода вы должны добавить к существующему массиву классов, чтобы не переопределять любые классы, которые были установлены ранее.

Клайв
источник
6
Я имею в виду обертку вокруг каждой радиокнопки, а не группы
volocuga
1
Это делается для всей группы радиостанций, а не для отдельных радиокнопок.
DrCord
1

Вы можете сделать выше (префикс / суффикс) для элементов в массиве параметров, тогда вы получите все, что вы хотите вокруг каждого элемента.

$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
источник
1
Я хочу верить, но это не для меня (D7). Вместо этого он просто вставляет префикс + суффикс как родственный элемент, непосредственно предшествующий индивидуально обернутым элементам опций. Может ли это быть опечатка, и действительно есть способ?
техас-брониус
Звучит так же, как вы добавляете div к несуществующей опции. Думаю, вы должны убедиться, что значения массива параметров соответствуют друг другу.
Strutsagget
Это определенно делает то, что говорит texas-bronius, добавляет отдельный элемент на том же уровне, что и переключатели, к сожалению, не рабочее решение.
DrCord
1

Я смог добиться этого после большой работы и пробовал каждый опубликованный метод, используя умный совет, который я нашел глубоко в Интернете на другом сайте: http://e9p.net/altering-individual-radio-or-checkbox-items-drupal- 7-фапи , чтобы #after_buildможно было изменять отдельные элементы формы, если они являются массивом друпал рендеринга.

Я хотел, чтобы каждое радио было упаковано в контейнер с классом, поэтому я использовал #prefixи #suffixдля этого:

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

пример использования:

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

Однако если вы хотите, чтобы inputэлемент имел только класс, вам нужно реализовать решение, которое я разместил на drupal.org по адресу https://api.drupal.org/comment/60197#comment-60197, чтобы разрешить использование #options_attributes. правильно для индивидуальных вариантов. Повторно опубликовать код здесь:

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

пример использования:

$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
источник
0

Единственный способ добиться этого - создать разные элементы формы для каждого радио, вручную связать имена с помощью #name и вручную установить значение с помощью #attributes. (#value по какой-то причине не работает.)

Например:

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

Это добавит оболочку и класс к отдельным переключателям, а не к группе переключателей, как это делает принятый в настоящее время ответ.

Визуализируйте
источник