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?
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.
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 fonction de thème, ou vous pouvez créer une fonction de thème de wrapper distincte et l'utiliser). Enfin, vous ajoutez une propriété #theme
À un élément de formulaire particulier, et cet élément obtiendra votre thème personnalisé.
Vous pouvez créer un fichier de modèle appelé form_element.tpl.php
Qui a simplement le comportement par défaut de theme_form_element()
puis 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.
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>';
}
Pour modifier le "wrapper", vous devez remplacer form_element. Fondamentalement, tous les éléments du formulaire sont rendus avec le thème form_element theme_form_element($element,$value);
(fichier form.inc)
Donc, pour changer la façon dont cela rend vos éléments de formulaire, copiez simplement cette fonction dans votre dossier template.php et renommez-la en: phptemplate_form_element($element,$value)
vous pouvez maintenant apporter des modifications et elles seront utilisées à la place de la fonction d'origine
theme_form_element($element,$value);
de form.incphptemplate_form_element($element,$value)
Vous pouvez utiliser la propriété wrapper_attributes.
$form['example'] = [
'#type' => 'textfield',
'#title' => $this->t('Example'),
'#wrapper_attributes' => ['class' => ['wrapper-class']],
];
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]
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';
}
Il y a des cas où ni #prefix/#suffix
Ni #attributes => array('class')
ne 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/#suffix
Cré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 [id$="-ajax-wrapper"]
Mais les deux ciblent plus que les éléments que je voulais.
La solution que j'ai trouvée est d'ajouter un élément #process
au formulaire et de manipuler manuellement le code de l'élément. Voici l'attribut #process
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 fonction mymodule_managed_file_process()
:
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 str_replace
À vos risques et périls. 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">
Vous pourriez utiliser
'#prefix' => '<div class="new_class">', '#suffix' => '</div>'
et cela l'enroulera