Changer de classe sur le wrapper div d'un élément de formulaire


11

Existe-t-il un moyen d'ajouter ou de modifier une classe dans un wrapper de formulaire (les div) à l'aide de l'API de formulaire?

Ou est-ce juste fait avec la fonction thème?

Si oui, quelle fonction de thème est utilisée pour changer cela?


Je suis sûr que c'est une fonction de thème. Quelle fonction de thème utiliser est la question. :)
akalata

Ah tu es là.
chrisjlee

Je pense que vous pouvez également utiliser la touche #attribute pour définir une classe
Mika A.

@Mika A. Cela ne s'applique qu'à la balise <input>, je voudrais changer la classe du wrapper (un <div>).
chrisjlee

Réponses:


5

Vous pouvez remplacer theme_form_element()normalement si vous souhaitez modifier le thème globalement. Si vous souhaitez modifier un seul élément de formulaire spécifique, je suis conscient de deux choix.

  1. Vous pouvez enregistrer une nouvelle fonction de thème pour le type particulier d'élément de formulaire qui vous intéresse (par exemple, champ de texte). Vous créez ensuite cette fonction de thème (basée sur l'original, par exemple theme_textfield()) mais qui n'appelle pas theme('form_element', ...)à la fin (vous pouvez soit gérer à la fois le wrapper et l'élément dans la seule fonction de thème, ou vous pouvez créer une fonction de thème de wrapper distincte et l'utiliser). Enfin, vous ajoutez une #themepropriété à un élément de formulaire particulier, et cet élément obtiendra votre thème personnalisé.

  2. Vous pouvez créer un fichier de modèle appelé form_element.tpl.phpqui a simplement le comportement par défaut de theme_form_element(), puis l'utiliser hook_preprocess_form_element()pour ajouter une suggestion de modèle. Ensuite, vous créez le nouveau modèle qui correspond à la suggestion. Vous entendez souvent des gens mentionner que les modèles sont légèrement plus lents que les fonctions, et pour un appel à thème aussi fréquemment utilisé, j'imagine que les gens hésitent à utiliser un modèle. Je n'ai cependant jamais fait de mesures pour cela moi-même. De plus, vous devez avoir suffisamment de contexte au stade du prétraitement pour pouvoir faire la suggestion.


Pourriez-vous fournir un exemple?
chrisjlee

@ ChrisJ.Lee Voulez-vous changer le wrapper de tous les éléments, ou juste un en particulier?
Andy

juste un seul.
chrisjlee

@chrisjlee J'ai mis à jour la réponse.
Andy

4

Je sais que c'est un super vieux fil, mais j'ai appris à modifier des éléments de formulaire et à ajouter des classes. Je me suis mis à créer un module personnalisé:

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

C'est une bonne solution alternative - n'ajoutez pas de classe à la div de wrapping, enveloppez simplement la div de wrapping dans votre propre div et vous pourrez appliquer les classes de votre choix.
Felix Eve

3

Pour modifier le "wrapper", vous devez remplacer form_element. Fondamentalement, tous les éléments du formulaire sont rendus avec le thème theme_form_element($element,$value);form_element (fichier form.inc)

Donc, pour changer la façon dont cela rend vos éléments de formulaire, il vous suffit de copier cette fonction dans votre dossier template.php et de la renommer: phptemplate_form_element($element,$value)

vous pouvez maintenant apporter des modifications et elles seront utilisées à la place de la fonction d'origine

  1. Copier theme_form_element($element,$value);depuis form.inc
  2. Collez-le dans (votre thème) template.php
  3. renommez-le en: phptemplate_form_element($element,$value)
  4. effacer tout le cache de thème
  5. Apportez les modifications que vous souhaitez et elles seront utilisées.

1

Vous pouvez utiliser la propriété wrapper_attributes .

$form['example'] = [
  '#type' => 'textfield',
  '#title' => $this->t('Example'),
  '#wrapper_attributes' => ['class' => ['wrapper-class']],
];

Cette réponse m'a aidé, mais notez qu'elle s'applique spécifiquement à Drupal 8.x et versions ultérieures.
Will Martin

0

Surtout, theme_form_element ne modifiera que le div wrapper parent direct et cela peut ne pas être la cible prévue pour les effets CSS.

[Bien que non programmatique, si l'on veut simplement appliquer une classe au top-wrapper d'un champ de noeud (c'est wrapper, wrapper, wrapper) on peut supposer utiliser le module "Field group" en sélectionnant "Manage Fields" pour un type de contenu particulier et sélectionnez "Ajouter un nouveau groupe" comme simple DIV. Ensuite, l'étiquette peut être supprimée et les classes souhaitées attribuées au wrapper supplémentaire (mais maintenant nous avons encore plus de wrappers) - avec une imbrication illimitée]


0

Vous pourriez utiliser

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

et cela l'enroulera


0

Rendez les attributs de wrapper configurables!

Créez votre propre fonction de thème d'élément de formulaire dans votre thème ... 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";

  ...
}

Ensuite, vous pouvez faire des choses comme ça ...

function my_module_form_alter(&$form, &$form_state, $form_id) {
  $form['account']['mail']['#my_theme_wrapper_attributes']['class'][] = 'form-field--inline';
}

0

Il y a des cas où ni #prefix/#suffixne #attributes => array('class')donnent les résultats souhaités. Mon cas particulier est l'ajout d'une classe à la div ajax-wrapper autour d'un élément managed_file. #prefix/#suffixcrée un nouveau conteneur et #attributes/'class'modifie la classe d'un élément interne, pas le plus externe.

Le div extérieur le plus normal est juste

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

ce qui est difficile à cibler en CSS. Je peux cibler [id^="edit-doc"]ou les [id$="-ajax-wrapper"]deux cibler plus que les éléments que je voulais.

La solution que j'ai trouvée est d'ajouter un #processélément au formulaire et de manipuler manuellement le code de l'élément. Voici l' #processattribut ajouté à la déclaration de l'élément de formulaire:

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

Et voici la mymodule_managed_file_process()fonction:

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

S'appuyer sur la substitution de chaînes n'est pas très portable, alors utilisez-le str_replaceà vos propres risques. Ce code, cependant, modifie en effet le DIV le plus externe pour ajouter la classe nécessaire:

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

-1
<?php
    $form['#attributes'] = array('class' => 'your-class-name');
?> 

Vous pouvez utiliser la méthode ci-dessus pour ajouter une classe sur l'élément de formulaire.


6
Comment modifieriez-vous alors la classe du div? Le code ci-dessus modifie la classe de la balise <input />.
chrisjlee

1
Cette réponse est incorrecte pour la question spécifique posée ici.
doublejosh
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.