Champ booléen et icône Django admin

30 Sep

Actuellement en plein développement d'une application Django, je me suis retouvé confronté à un petit problème "Comment faire pour afficher les icones de base d'un champ booléen dans l'administration de Django", quand celui-ci est éditable, je n'ai pas cherché bien longtemps je suis tombé sur cette question sur stackoverflow, la solution est simple mais ne fonctionne pas, je me suis donc inspiré de ce script pour en créer un et qui fonctionne bien sur la verison 1.6 de Django

Pour illustrer ma problematique voici à quoi ressemble un champ booléen non éditable (image de gauche) et  un champ  booléen éditable (image de droite) dans l'administration de django:
Champ booléen editable Django adminchamp-booléen-django-admin

Ajout d'un script JS dans la Class Media

La solution est assez simple est nécessite la création d'un petit script JS, qui permettra d'ajouter les images à la place de la checkbox en question et ainsi de changer l'image lors des differents états (pas checked ou checked).
Commençons d'abord  dans votre fichier admin.py, l'ajout de la classe Media dans le model qui intégre votre champ booléen, cela nous permettra d'ajouter notre script JS dans notre listing d'objets.

class Media:
    from django.conf import settings
    media_url = getattr(settings, 'MEDIA_URL')
js = (media_url + 'admin/bool_field_icons.js',

Ici j'ai simplement ajouter dans mon attribut js l'url de mon fichier qui s'appel bool_field_icons.js, vous devez bien entendu l'adapter à votre chemin et nom de votre script.

Développement du script JS

Voici le script JS en question et commenté:

 
(function($){
    
    //Pour commencer on va initialiser 2 variables, qui vont stocker 
    //chacune d'elle une image se référant aux différents états (pas selectionnée, et selectionnée)
    var on_image  = '/static/admin/img/icon-yes.gif';
    var off_image = '/static/admin/img/icon-no.gif';
    
    $(document).ready(function(){
        // On cherche tous les champ de type checkbox et on boucle en ajoutant une fonction
        $('input[type=checkbox]').each(function(){
            // On check la class du body pour que seul la checkbox du listing soit affectée (change_list)
            var $body_class = $('body').attr('class').split(' ')[1];
            var $this       = $(this);
            var $id         = $this.attr('id');

            // Regex if checkbox id end by "active"
            var regex = /active$/;
            
            // on test si le regex a bien la chaine de caractère "active" et que la page n'est pas "change-form"
            if(regex.test($id) && $body_class != 'change-form') {
                
                // On ajoute la classe "checkbox-icon"
                $this.addClass('checkbox-icon');
                
                // On cache les checkboxes"
                var $checkbox = $('.checkbox-icon#'+$id).hide();

                var $img = $('img');
                
                // condition suivant l'état on ajoute l'image correspondante
                if ($checkbox.attr('checked')) {
                    $img.attr('src', on_image);
                    $img.attr('alt', 'True');
                } else {
                    $img.attr('src', off_image);
                    $img.attr('alt', 'False');
                }
                $img.insertAfter($checkbox);
                
                // Ajoute de l'évenement "click" permettant au click l'ajout de la valeur
                // et du changement d'image
                $img.click(function(){
                    var $img = $(this);
                    var $checkbox = $img.siblings('input');
                    if ($img.attr('src') == on_image) {
                        $img.attr('src', off_image);
                        $img.attr('alt', 'False');
                        $checkbox.attr('checked', false);
                    } else {
                        $img.attr('src', on_image);
                        $img.attr('alt', 'True');
                        $checkbox.attr('checked', true);
                    }
                });
            }
        });
    });
})(django.jQuery);

Biensur il faudra adapter le script en fonction de vos classes, etc.
Le script fonctionne sous Django 1.6.5 mais devrait fonctionner sur d'autres versions, à vous de personnaliser le script
comme bon vous semble.

SI vous avez des questions ou amélioration à suggérer n'hésitez à m'en faire par dans les commentaires.

Publié le: Mardi 30 septembre 2014
blog comments powered by Disqus
Monter

© Circonflex-studio - Tous droits réservés - Mentions legales
Développeur web indépendant / Webdesigner / Intégrateur
Nice - Cannes - Monaco - Antibes - côte d'azur | site valide HTML 5

Ce site à été développé en Python avec le framework Django

"http://www.cssawards.net/nominee/circonflex-studio/"