remplacer le texte des items radios dans un formulaire par des images

Information importante

En raison d'un grand nombre d'inscriptions de spammers sur notre site, polluant sans relache notre forum, nous suspendons la création de compte via le formulaire de "sign up".

Il est néanmoins toujours possible de devenir adhérent•e en faisant la demande sur cette page, rubrique "Inscription" : https://www.drupal.fr/contact


De plus, le forum est désormais "interdit en écriture". Il n'est plus autorisé d'y écrire un sujet/billet/commentaire.

Pour contacter la communauté, merci de rejoindre le slack "drupalfrance".

Si vous voulez contacter le bureau de l'association, utilisez le formulaire disponible ici, ou envoyez-nous un DM sur twitter.

Bonjour,
J'ai un formulaire avec un éléments radios. J'aimerais remplacer les textes de chaque bouton par une image.
Quelqu'un a-t'il une idée de la façon de procéder ?
Merci de vos réponses
Timos

Forum : 
Version de Drupal : 
Tags : 

Autant pour moi, cela n'était pas très compliqué (si peu que je pensais pas que ça pouvait marcher comme cela d'ailleurs ... j'ai du oublié que je bossais avec drupal ;-) !)

Donc pour info, il est tout à fait possible de mettre des images à la place de texte au niveau des bouton radio, pour cela, dans la fonction définissant le formulaire il suffit de faire :

<?php
// debut de la fonction form
// ...
$form['radios_images'] = array(
 
'#type" => 'radios',
  '
#options' => array(
    
1 => '<img src="url_image_1" alt="alt_img_1" />',
    
2 => '<img src="url_image_2" alt="alt_img_2" />',
    
3 => '<img src="url_image_3" alt="alt_img_3" />',
   ),
);
// suite de la fonction form
?>

pour l'url des images il est bien sûr recommandé de ne pas mettre celle-ci en dur, mais d'utiliser la globale $base_path couplée à la fonction drupal_get_path($type, $name) du style :

<?php
$url_image
= $base_path . drupal_get_path('theme','mon_theme') . '/images/fichier_image.jpg';
?>

Salut,
Pour éviter une réponse de 200 lignes (je peux être verbeux quand je m'y mets ;-)), tu veux modifier un formulaire existant au préalable (généré par un module du core ou un module 'contrib') ou créer un formulaire de toutes pièces (la méthode ne sera alors pas la même, d'où ma question).

Si tu veux créer un formulaire de toutes pièces, tu peux jeter un oeil sur la doc concernant les formulaires, n'hésite pas ensuite à demander deux ou trois trucs dans ce post.

S'il s'agit de modifier un formulaire, la méthode que je décris plus haut demande la mise en place d'un hook_form_form_id_alter(&$form, &$form_state), donc soit d'incorporer ce hook dans un module custom pre existant, soit de créer un petit module.

Ensuite, tout cela peut être long a expliquer sans cas concret donc, le mieux est de me dire quel formulaire tu veux modifier et j'essaie de voir ça

A+

Tim

Salut,

Mon formulaire existe. C'est un multiform avec des champs CCK. Je n'ai pas créer de fonction comme expliqué dans la doc !

Un des champs doit être composé d'émoticons cliquables. Il y a cinq gif correspondant à cinq émotions.

J'ai donc créer un champ de type texte de type radio button avec le code ci-dessous comme valeur autorisée en Php :

$form['radios_images'] = array(
  '#type" => 'radios',
  '#options' => array(
     1 => '<img src="/sites/www.vaiia.com/themes/emotion1_off.gif" alt="content1" />',
     2 => '<img src="/sites/www.vaiia.com/themes/emotion2_off.gif" alt="alt_img_2" />',
     3 => '<img src="/sites/www.vaiia.com/themes/emotion3_off.gif" alt="alt_img_3" />',
   )
);

Mais ça n'affiche rien :-(

Merci

ok, pour du cck effectivement cela peut aller plus vite de tout de suite entrer ça en valeur php autorisées (bien qu'il y ait de fortes chances que les fonctions de cck qui gèrent ça te passent le contenu dans des fonctions désactivant le html, mais bon ça se tente).

Donc dans ce cas, essaie plutôt un truc comme ça (la syntaxe que j'ai donnée ne fonctionne qu'au sein de l'api form, donc dans des fichiers php, enfin à ma connaissance) : dans le champ valeurs autorisées en php entre (sans les balises ouvrante et fermante php, ça c'est uniquement pour avoir la bonne colorisation ici
:

<?php
return array(
    
1 => '<img src="/sites/www.vaiia.com/themes/emotion1_off.gif" alt="content1" />',
    
2 => '<img src="/sites/www.vaiia.com/themes/emotion2_off.gif" alt="alt_img_2" />',
    
3 => '<img src="/sites/www.vaiia.com/themes/emotion3_off.gif" alt="alt_img_3" />',
   );
?>

Merci de ton aide

Le html semble effectivement désactivé puisque ça ne passe pas.

En utilisant juste le champ html des valeurs autorisées, j'arrive à afficher les images mais comment pourrai-je rendre les images cliquables à la place des boutons radios ?

Hello à nouveau,
Bon j'ai testé la solution dans les champs valeurs autorisées et valeurs autorisées php, et cela fonctionne pour les deux.
Par contre l'image apparaît également en mode consultation.

Si cela ne fonctionnait pas, c'est peut être que ton chemin vers l'image n'est pas le bon. Mais dans ce cas tu devrais avoir le text de l'attribut alt qui apparaît ?

Enfin en tout cas le code suivant fonctionne (sans les balises ouvrante et fermante php :

<?php
return array(
 
1 => '<img src="pathtoimage/image1.jpg" alt="mon image 1" />',
 
2 => '<img src="pathtoimage/image2.jpg" alt="mon image 2" />',
 
3 => '<img src="pathtoimage/image3.jpg" alt="mon image 3" />',
);
?>

deux conseils :
pour ton type de champ, choisi un champ numérique, c'est la clé du tableau qui est enregistré et qui renvoit le chemin de l'image.

pour le chemin de ton image, place tes images dans ton thèmes, par exemple dans un le répertoire sites/all/themes/ton_theme/images/bouton_radio et ensuite utilise la fonction drupal_get_at() pour le retrouver (d'où l'intérêt d'utiliser le champ valeurs autorisées php : ça donnerait un truc du genre :

<?php
$path
= drupal_get_path('theme', 'ton_theme') . '/images/bouton_radio/';
return array(
 
1 => '<img src="' . $path . 'image1.jpg" alt="mon image 1" />',
 
2 => '<img src="' . $path . ' image2.jpg" alt="mon image 2" />',
 
3 => '<img src="' . $path . 'image3.jpg" alt="mon image 3" />',
);
?>

Encore une fois, dans ce cas, tu te retrouves avec l'image quand une personne consulte le node crée.

A+

Hello,
Oui effectivement, ma méthode permet de remplacer la proposition par une image et non les boutons radios en eux-même.

Si tu veux créer des boutons radio custom(désolé je n'avais pas compris ça comme cela - mon sujet concerne bien le remplacement du texte par des images et non le remplacement des boutons radio) regarde du côté de
http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/ pour les généralités
et ensuite il faudra mettre un peu les mains dans le cambouis.
quelques pistes (c'est donné comme ça à brule pourpoint donc il y'a peut être de meilleures solutions) :

  • utiliser une fonction de type tontheme_radio($element) que tu places dans le fichier template.php de ton theme.
    Tu peux récupérer l'original de cette fonction (theme_radio($element)) dans le fichier includes/form.inc, ligne1542 dans la version 6.17 de drupal). Tu as juste à recopier cette fonction est à ajouter la classe "styled" à l'élément input généré par cette fonction. (voir code plus bas)
  • ensuite tu n'as plus qu'à appliquer la méthode donnée dans le lien ci-dessous, en ajoutant le fichier .js dans ton fichier tontheme.info (cf code ci-dessous) et en modifiant le css comme indiqué dans la méthode)

Encore une fois, c'est une solution parmi d'autres, et elle ne fonctionne que si tu veux remplacer l'ensemble de tes boutons radios (ainsi que les checkboxes et les liste select)
Si tu veux ne remplacer que quelques boutons, un petit jquery (qui doit s'exécuter avant le script fourni sur la page donné en lien) devrait te permettre d'ajouter la class "styled" au bouton que tu veux avec un petit

<script>
$('#id_du_bouton').addClass('styled');
</script>

Pour la méthode générale :
mettre en place la fonction tontheme_radio($element)

<?php
// ATTENTION : j'ai ré écris la fonction à l'arrache, je vais la tester et éventuellement la corriger.
function tontheme_radio($element) {
 
_form_set_class($element, array('form-radio'));
 
// on modifie la classe via l'élément $element['#attributes']['class']
 // si l'élément n'a pas d'attribut class défini on le crée
 
if(!isset($element['#attributes']['class']) {
    
$element['#attributes']['class'] = "styled";
  }
 
// sinon on ajoute la valeur "styled" à la fin de la chaîne de valeur de l'attribut
 
else {
   
$element['#attributes']['class'] .= " styled";
  }
 
$output = '<input type="radio" ';
 
$output .= 'id="'. $element['#id'] .'" ';
 
$output .= 'name="'. $element['#name'] .'" ';
 
$output .= 'value="'. $element['#return_value'] .'" ';
 
$output .= (check_plain($element['#value']) == $element['#return_value']) ? ' checked="checked" ' : ' ';
 
$output .= drupal_attributes($element['#attributes'])' />';
  if (!
is_null($element['#title'])) {
   
$output = '<label class="option" for="'. $element['#id'] .'">'. $output .' '. $element['#title'] .'</label>';
  }

  unset($element['#title']);
  return
theme('form_element', $element, $output);
}
?>

Modif du fichier tontheme.info

;ligne à ajouter, où scripts est le chemin du fichier dans ton thème
;et custom-form-elements.js le fichier js à récupérer sur la page donnée en lien
scripts[] = scripts/custom-form-elements.js

Bon, j'ai testé ma solution, ça marche (au niveau de la fonction tontheme_radio, je n'ai pas testé la suite) mais il y a plus simple.

D'une part au lieu de faire :

<?php
function tontheme_radio($element) {
 
_form_set_class($element, array('form-radio'));
 
// on modifie la classe via l'élément $element['#attributes']['class']
// si l'élément n'a pas d'attribut class défini on le crée
if(!isset($element['#attributes']['class']) {
    
$element['#attributes']['class'] = "styled";
  }
 
// sinon on ajoute la valeur "styled" à la fin de la chaîne de valeur de l'attribut
 
else {
   
$element['#attributes']['class'] .= " styled";
  }
 
$output = '<input type="radio" ';
 
$output .= 'id="'. $element['#id'] .'" ';
 
$output .= 'name="'. $element['#name'] .'" ';
 
$output .= 'value="'. $element['#return_value'] .'" ';
 
$output .= (check_plain($element['#value']) == $element['#return_value']) ? ' checked="checked" ' : ' ';
 
$output .= drupal_attributes($element['#attributes'])' />';
  if (!
is_null($element['#title'])) {
   
$output = '<label class="option" for="'. $element['#id'] .'">'. $output .' '. $element['#title'] .'</label>';
  }

  unset($element['#title']);
  return
theme('form_element', $element, $output);
}
?>

On remarque la petite fonction _form_set_class($element, array('form-readio') à laquelle je n'avais pas pris garde et qui en fait, fait exactement ce que l'on veut faire : cad ajouter des classes à l'élément il suffit donc de faire :

<?php
function tontheme_radio($element) {
 
// on ajoute la classe styled
 
_form_set_class($element, array('form-radio', 'styled'));
 
$output = '<input type="radio" ';
 
$output .= 'id="'. $element['#id'] .'" ';
 
$output .= 'name="'. $element['#name'] .'" ';
 
$output .= 'value="'. $element['#return_value'] .'" ';
 
$output .= (check_plain($element['#value']) == $element['#return_value']) ? ' checked="checked" ' : ' ';
 
$output .= drupal_attributes($element['#attributes'])' />';
  if (!
is_null($element['#title'])) {
   
$output = '<label class="option" for="'. $element['#id'] .'">'. $output .' '. $element['#title'] .'</label>';
  }

  unset($element['#title']);
  return
theme('form_element', $element, $output);
}
?>

mais il y a encore plus simple, sans modifier la fonction theme_radio et en n'appliquant uniquement la méthode donnée à la page
http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/.
Il suffit de charger le fichier custom-form-elements.js (via le fichier tontheme.info comme expliquer dans le post précédent par exemple) et dans ce fichier (custom-form-elements.js) de remplacer les mentions "styled" par "form-radio", puisque cette classe est attribuée de base à tous les éléments radio...

Dans les deux cas il faut prendre garde aux conflits de css, le script semble donner respectivement les classes radio, checkbox et select aux éléments de types radio, checkbox et select

hum autant pour moi, si je ne m'abuse, la fonction drupal_get_path() renvoit directement le chemin complet relatif au documentRoot du serveur sur lequel tourne le site, donc pas besoin de la variable $base_path.

Autre astuce qui évite une requête sql, au lieu d'utiliser la fonction drupal_get_path, il existe une global theme_path, qui renvoit le thème courant, cf http://api.drupal.org/api/function/drupal_get_path/6#comment-1423

je vais regarder ça cet aprem', je te tiens au courant.
Si tu ne peux pas faire ça en admin, il va falloir passer par un petit module perso.
pour commencer tu peux regarder les bases sur le site arnumeral (si tu n'as jamais développer de module)
je te tiens au courant dans la journée ou au plus tard demain
Ciao