Div Wrapper um ein bestimmtes Optionsfeld hinzufügen / ändern?

7

Standardmäßig sieht das HTML-Markup für Optionsfelder wie folgt aus (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>

Ich muss einige CSS-Klassen im äußeren ändern / hinzufügen <div>ODER einen Wrapper hinzufügen <div>. Wie mache ich das?

Volocuga
quelle
1
Haben Sie jemals herausgefunden, wie das geht?
Dominic
Ich frage mich, ob Sie in Ihrem "standardmäßig" Drupal-Theming von Radios klären könnten, woher die -SOME_ID kommt. Um die Variablen zu nivellieren, habe ich zum Thema Sieben gewechselt und sehe immer noch nur die ID der
Funkgruppe

Antworten:

9

Wenn Sie das Formular selbst definieren, können Sie ein Element mithilfe der Eigenschaften #prefixund mit HTML #suffixumschließen:

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

Wenn Sie dem vorhandenen Wrapper eine Klasse hinzufügen möchten, können Sie dies über die #attributesEigenschaft tun :

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

Wenn Sie das Formular nicht selbst definieren, können Sie dennoch dieselbe Logik verwenden und a implementieren hook_form_alter(), um das vorhandene Formular zu ändern:

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

Beachten Sie, dass Sie bei Verwendung der hook_form_alter()Methode an das vorhandene Klassenarray anhängen sollten, um keine zuvor festgelegten Klassen zu überschreiben.

Clive
quelle
6
Ich meine Wrapper um jedes
Optionsfeld
1
Dies gilt für die gesamte Gruppe von Funkgeräten, nicht für die einzelnen Optionsfelder.
DrCord
1

Sie können die oben genannten Schritte (Präfix / Suffix) für die Elemente im Optionsarray ausführen, um dann für jedes Element alles zu erhalten, was Sie möchten.

$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
quelle
1
Ich möchte glauben, aber das tut es nicht für mich (D7). Stattdessen wird nur das Präfix + Suffix als Geschwisterelement unmittelbar vor den einzeln div-umschlossenen Optionselementen eingefügt. Könnte es ein Tippfehler sein und es gibt wirklich einen Weg?
Texas-Bronius
Klingt so, als würden Sie das div zu einer nicht vorhandenen Option hinzufügen. Denken Sie, Sie müssen sicherstellen, dass die Array-Werte der Optionen übereinstimmen.
Strutsagget
Dies macht definitiv das, was Texas-Bronius sagt, fügt ein separates Element auf der gleichen Ebene wie die Optionsfelder hinzu, leider keine funktionierende Lösung.
DrCord
1

Ich konnte dies erreichen, nachdem ich viel gearbeitet und jede veröffentlichte Methode mit einem intelligenten Tipp ausprobiert hatte, den ich tief im Internet auf einer anderen Website gefunden hatte: http://e9p.net/altering-individual-radio-or-checkbox-items-drupal- 7-fapi , um das Formelement#after_build einzelner Radios ändern zu können, sobald sie ein Drupal-Render-Array sind.

Ich wollte, dass jedes Radio in einen Container mit einer Klasse eingewickelt wird, also benutzte ich #prefixund #suffixtat das:

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

Beispiel verwenden:

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

Wenn Sie jedoch nur möchten, dass das inputElement die Klasse hat, müssen Sie die Lösung implementieren, die ich auf drupal.org unter https://api.drupal.org/comment/60197#comment-60197 veröffentlicht habe , damit die #options_attributes verwendet werden können richtig für einzelne Optionen. Code hier erneut veröffentlichen:

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

Beispiel verwenden:

$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
quelle
0

Die einzige Möglichkeit, dies zu erreichen, besteht darin, für jedes Funkgerät ein anderes Formularelement zu erstellen, die Namen manuell mit #name zu koppeln und mit #attributes manuell einen Wert festzulegen. (#value funktioniert aus irgendeinem Grund nicht.)

Zum Beispiel:

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

Dadurch werden den einzelnen Optionsfeldern anstelle der Optionsgruppe ein Wrapper und eine Klasse hinzugefügt, wie dies bei der aktuell akzeptierten Antwort der Fall ist.

Visualisieren
quelle