Zmień klasę na opakowaniu div elementu formularza

11

Czy istnieje sposób na dodanie lub zmianę klasy do opakowania formularza (div) za pomocą interfejsu API formularza?

Czy to właśnie zrobiono z funkcją motywu?

Jeśli tak, to jakiej funkcji motywu używa się do zmiany tego?

chrisjlee
źródło
Jestem pewien, że to funkcja motywu. Która funkcja motywu ma być użyta, to pytanie. :)
akalata
Ach, jesteś tam.
chrisjlee
Myślę, że możesz także użyć klawisza #attribute do zdefiniowania klasy
Mika A.
@Mika A. Dotyczy to tylko znacznika <input>, który chciałbym zmienić klasę opakowania (<div>).
chrisjlee

Odpowiedzi:

5

Możesz zastąpić theme_form_element()normalnie, jeśli chcesz zmienić temat globalnie. Jeśli chcesz zmodyfikować tylko jeden określony element formularza, mam świadomość kilku opcji.

  1. Możesz zarejestrować nową funkcję motywu dla określonego typu elementu formularza, który Cię interesuje (np. Pole tekstowe). Następnie tworzysz tę funkcję motywu (na podstawie oryginału, np. theme_textfield()), Ale to nie wywołuje theme('form_element', ...)na końcu (możesz obsługiwać zarówno opakowanie, jak i element w funkcji jednego motywu, lub możesz utworzyć osobną funkcję motywu opakowania i użyj tego). Na koniec dodajesz #themewłaściwość do określonego elementu formularza, a ten element otrzyma niestandardowe motywy.

  2. Możesz utworzyć plik szablonu o nazwie, form_element.tpl.phpktóry ma tylko domyślne zachowanie, theme_form_element()a następnie użyć go, hook_preprocess_form_element()aby dodać sugestię szablonu. Następnie tworzysz nowy szablon, który pasuje do sugestii. Często słyszysz, jak ludzie wspominają, że szablony są nieco wolniejsze niż funkcje, a przy tak często używanym wywołaniu motywu mogę sobie wyobrazić, że ludzie nie chcą używać szablonu. Jednak sam nigdy nie dokonałem żadnych pomiarów. Ponadto musisz mieć wystarczającą ilość kontekstu na etapie wstępnego przetwarzania, aby móc przedstawić sugestię.

Andy
źródło
Czy możesz podać przykład?
chrisjlee
@ ChrisJ.Lee Czy chcesz zmienić opakowanie dla wszystkich elementów, czy tylko jednego konkretnego?
Andy
tylko jeden.
chrisjlee
@chrisjlee Zaktualizowałem odpowiedź.
Andy
4

Wiem, że to bardzo stary wątek, ale uczyłem się, jak zmieniać elementy formularza i dodawać klasy. Zacząłem tworzyć niestandardowy moduł:

function yourtheme_custom_form_alter(&$form, &$form_state, $form_id) {
 case'webform_number_whatever':
   _yourtheme_form_add_wrapper($form['submitted']['yourfieldhere'], array('form-field-some-style', 'not-label', 'whatever-other-styles-you-want'));
 break;
}

function _yourtheme_form_add_wrapper(&$element, $classes = array(), $type = array('form-item', 'form-type-textfield'), $removeTitle = FALSE){
  $element['#prefix'] = '<div class="' . implode(" ", $classes) . '"><div class="' . implode(" ", $type) . '">';
  $element['#suffix'] = '</div></div>';
}
tdm
źródło
Jest to dobre alternatywne rozwiązanie - nie dodawaj klasy do zawijającego div, po prostu zawijaj div zawijający we własnym divie, a możesz zastosować dowolne klasy.
Felix Eve
3

Aby zmienić „opakowanie”, musisz zastąpić element_formularz. Zasadniczo wszystkie elementy formularza są renderowane za pomocą kompozycji theme_form_element($element,$value);form_element (plik form.inc)

Aby zmienić sposób renderowania elementów formularza, wystarczy skopiować tę funkcję do folderu template.php i zmienić jej nazwę na: phptemplate_form_element($element,$value)

teraz możesz wprowadzić dowolne zmiany i zostaną one użyte zamiast oryginalnej funkcji

  1. Skopiuj theme_form_element($element,$value);z form.inc
  2. Wklej go do (twój motyw) template.php
  3. zmień nazwę na: phptemplate_form_element($element,$value)
  4. wyczyść całą pamięć podręczną motywu
  5. wprowadź dowolne zmiany, a zostaną one użyte.
Andre
źródło
1

Możesz użyć właściwości wrapper_attributes .

$form['example'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Example'),
  '#wrapper_attributes' => ['class' => ['wrapper-class']],
];
ya.teck
źródło
Ta odpowiedź pomogła mi, ale zauważ, że dotyczy ona w szczególności Drupala 8.xi późniejszych.
Czy Martin
0

Co ważne, theme_form_element zmodyfikuje tylko div bezpośredniego opakowania nadrzędnego i może to nie być zamierzony cel dla efektów CSS.

[Chociaż nie jest to programowe, jeśli ktoś chce po prostu zastosować klasę do górnego opakowania pola węzła (to jest opakowanie, opakowanie, opakowanie), można przypuszczać, że można użyć modułu „Grupa pól”, wybierając opcję „Zarządzaj polami” dla określonego typu treści i wybierz „Dodaj nową grupę” jako prosty DIV. Następnie można usunąć etykietę i przypisać pożądane klasy do dodatkowego opakowania (ale teraz mamy jeszcze więcej opakowań) - z nieograniczonym zagnieżdżaniem]

użytkownik24737
źródło
0

Możesz użyć

'#prefix' => '<div class="new_class">', '#suffix' => '</div>'

i to go obejmie

Alex
źródło
0

Ustaw atrybuty opakowania konfigurowalne!

Utwórz własną funkcję motywu elementu formularza w swoim motywie ... sites/all/themes/MY_THEME/theme/form-element.theme.inc

function my_theme_form_element($variables) {
  $element = &$variables['element'];

  $attributes = isset($element['#my_theme_wrapper_attributes']) ?
    $element['#my_theme_wrapper_attributes'] : array();

  ...

  $output = '<div' . drupal_attributes($attributes) . '>' . "\n";

  ...
}

Następnie możesz robić takie rzeczy ...

function my_module_form_alter(&$form, &$form_state, $form_id) {
  $form['account']['mail']['#my_theme_wrapper_attributes']['class'][] = 'form-field--inline';
}
doublejosh
źródło
0

Zdarzają się przypadki, w których ani #prefix/#suffixnie #attributes => array('class')dają pożądanych rezultatów. Moim szczególnym przypadkiem jest dodanie klasy do div otoki otoki ajax wokół elementu managed_file. #prefix/#suffixtworzy nowy kontener i #attributes/'class'modyfikuje klasę elementu wewnętrznego, a nie najbardziej zewnętrznego.

Normalny skrajny div jest po prostu

<div id="edit-doc1--XX-ajax-wrapper">

który jest trudny do celowania w CSS. Mogę kierować [id^="edit-doc"]albo [id$="-ajax-wrapper"]ale oba z tych cel więcej niż tylko elementy chciałem.

Rozwiązaniem, które wymyśliłem, jest dodanie #processelementu do formularza i ręczne manipulowanie kodem elementu. Oto #processatrybut dodany do deklaracji elementu formularza:

$form['doc1'] = array(
  '#type' => 'managed_file',
  '#process' => array('mymodule_managed_file_process'),
);

A oto mymodule_managed_file_process()funkcja:

function mymodule_managed_file_process($element, &$form_state, $form) {

  // Call the original function to perform its processing.
  $element = file_managed_file_process($element, $form_state, $form);

  // Add our own class for theming.
  $element['#prefix'] = str_replace(
    'id=',
    'class="managed-file-wrapper" id=',
    $element['#prefix']
  );

  return $element;
}

Poleganie na zamianie ciągów nie jest zbyt przenośne, więc używaj str_replacena własne ryzyko. Ten kod jednak rzeczywiście zmienia skrajne DIV, aby dodać niezbędną klasę:

<div class="managed-file-wrapper" id="edit-doc1--XX-ajax-wrapper">
Joseph Cheek
źródło
-1
<?php
    $form['#attributes'] = array('class' => 'your-class-name');
?> 

Możesz użyć powyższego sposobu, aby dodać klasę do elementu formularza.

Fero
źródło
6
Jak zmodyfikowałbyś klasę div? Powyższy kod zmienia klasę znacznika <input />.
chrisjlee
1
Ta odpowiedź jest błędna w przypadku konkretnego pytania zadanego tutaj.
doublejosh 18.03.16