Agenda en HTML/CSS (sans JS)

Le problème exposé dans ce sujet a été résolu.

Bonjour !

Je suis en ce moment entrain de créer un site web minimaliste (côté utilisateur) basé sur Python et Django, auquel j’aimerais ajouter un agenda. Or, je cherche à faire cela sans Javascript, donc en pur HTML/CSS (j’utilise également le framework Bulma.

Pour l’instant, je fais cela avec un tableau où les jours sont en lignes et les heures en colonnes. Chaque évènement a une durée qui définit l’attribut width de l’élément, et une heure de départ qui définit son attribut left (pour gérer le décalage, en pixels, par rapport à la première heure de la journée). Sachant qu’il peut y avoir plusieurs évènements en même temps. Quand c’est le cas, plusieurs lignes sont créées pour le même jour dans le tableau pour éviter les recouvrements. Chaque affichage de l’agenda comporte cinq jours (du lundi au vendredi), avec des horaires allant de 8h à 20h (mais je rajouterai peut-être plus tard une case de type "Toute la journée").

Sur un écran de taille fixe, mes essais fonctionnent. Toutefois, dès que l’écran devient plus petit que la largeur (fixe) du tableau, je ne parviens plus à avoir quelque chose d’utilisable. Du coup, je me demande si je ne serais pas entrain de réinventer la roue.

Sauriez-vous s’il existe déjà des frameworks ou des outils permettant de réaliser cela, si possible de manière à peu près responsive (s’il faut scoller, ça me convient aussi) ?

Merci d’avance ! :)

+0 -0

Je pense que tu t’orientes vers la bonne voie en choisissant un tableau. La plupart des gens utilises un tableur pour faire ce genre de chose.

Par-contre, il doit certainement exister des outils pour faire des tableaux de manière adaptative. Dans tous les cas, il existe des résultats assez intéressants pour les mots clés « Responsive table HTML ».

Bon courage.

@A-312: Agenda, pas calendrier.

Edit: Par-contre, je ne suis pas du tout convaincu par la bidouille du left même si je comprend l’idée. Je me dis que c’est assez dépendant des évènements de l’agenda et que du coup, il faudra tout recalculer au moindre changement.

+0 -0

Merci pour vos réponses ! :)

En effet, il se trouve que je calcule le rendu de l’agenda à la volée à chaque appel de la page, avec des boucles for imbriquées dans le template de la page. Que pense-tu que je devrais utiliser à la place ? Faire un tableau avec une colonne par tranche de 15 minutes et faire fusionner les cellules pour afficher les évènements serait-il suffisamment propre (en fusionnant 4 cellules pour un évènement d’une heure, par exemple) ?

Voilà le rendu actuel de mon prototype.

Merci ! :)

+0 -0

Perso, j’aurais créer des cellules vides blanches, pour chaque trou.

Quand l’écran sera trop petit, tu devras certainement afficher un jour par un jour en colonne.

+0 -0

Merci !

J’ai tenté quelque chose d’approchant et j’obtiens un résultat assez satisfaisant. Le seul problème qui persiste est que je dois jouer avec le CSS pour trouver les bons paramètres pour que l’agenda puisse tenir en entier sur mon écran (12 pouces). J’aimerais bien n’avoir à scroller que sur une tablette ou un téléphone…

Lorsque j’essaie de fixer la largeur des colonnes et une absence de padding, les colonnes ont malgré tout des tailles différentes. Auriez-vous une idée d’un moyen pour tout faire tenir avec une largeur harmonisée pour chaque colonne (qui représente pour l’instant 15 minutes) ?

Voilà ce que ça donne actuellement (rendu HTML de Django et capture d’écran).

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Agenda</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css">
        <!-- TODO: Se passer de FontAwesome. -->
        <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
        
    </head>
    <body>
        <section class="section">
            <div class="container">
              <h1 class="title">Agenda</h1>
            </div>
        </section>
        
        <style>
            .event {
                height: 100px;
            }
            
            th {
                width: 40px !important;
                padding-left: 0px !important;
                padding-right: 0px !important;
            }
        </style>
        
        <section class="section">
            <nav class="level">
                <div class="level-item">
                    <div class="field has-addons">
                        <p class="control">
                            <a class="button">
                                <span class="icon"><i class="fas fa-chevron-left"></i></span>
                            </a>
                        </p>
                        <p class="control">
                            <a class="button">
                                Semaine du 04/03 au 10/03
                            </a>
                        </p>
                        <p class="control">
                            <a class="button">
                                <span class="icon"><i class="fas fa-chevron-right"></i></span>
                            </a>
                        </p>
                    </div>
                </div>
            </nav>
            
            <table class="table" style="overflow-x: auto; display: block;">
                <thead>
                    <tr>
                        <th></th>
                            <th class="th_hour">08:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">09:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">10:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">11:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">12:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">13:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">14:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">15:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">16:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">17:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">18:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">19:00</th>
                            <th ></th>
                            <th ></th>
                            <th ></th>
                            <th class="th_hour">20:00</th>
                        
                    </tr>
                </thead>
                <tbody>
                            <tr>
                                <th>Lundi 04/03</th>
                                
                                    <td colspan="16">
                                        
                                    </td>
                                
                                    <td colspan="8">
                                        
                                            <article class="tile is-child notification is-primary event">
                                                <p class="title is-size-5">Pique-nique collectif</p>
                                                <p class="subtitle is-size-6">12:00 - 14:00</p>
                                            </article>
                                        
                                    </td>
                                
                                    <td colspan="16">
                                        
                                    </td>
                                
                                    <td colspan="8">
                                        
                                            <article class="tile is-child notification is-primary event">
                                                <p class="title is-size-5">Réunion d&#39;auto-gestion</p>
                                                <p class="subtitle is-size-6">18:00 - 20:00</p>
                                            </article>
                                        
                                    </td>
                                
                            </tr>
                        
                    
                        
                            <tr>
                                <th>Mardi 05/03</th>
                                
                                    <td colspan="16">
                                        
                                    </td>
                                
                                    <td colspan="8">
                                        
                                            <article class="tile is-child notification is-primary event">
                                                <p class="title is-size-5">Pique-nique collectif</p>
                                                <p class="subtitle is-size-6">12:00 - 14:00</p>
                                            </article>
                                        
                                    </td>
                                
                                    <td colspan="16">
                                        
                                    </td>
                                
                                    <td colspan="8">
                                        
                                            <article class="tile is-child notification is-primary event">
                                                <p class="title is-size-5">Ciné-débat</p>
                                                <p class="subtitle is-size-6">18:00 - 20:00</p>
                                            </article>
                                        
                                    </td>
                                
                            </tr>
                        
                    
                        
                            <tr>
                                <th>Mercredi 06/03</th>
                                
                                    <td colspan="48">
                                        
                                    </td>
                                
                                    <td colspan="48">
                                        
                                    </td>
                                
                                    <td colspan="48">
                                        
                                    </td>
                                
                            </tr>
                        
                    
                        
                            <tr>
                                <th>Jeudi 07/03</th>
                                
                                    <td colspan="48">
                                        
                                    </td>
                                
                                    <td colspan="48">
                                        
                                    </td>
                                
                                    <td colspan="48">
                                        
                                    </td>
                                
                            </tr>
                        
                    
                        
                            <tr>
                                <th>Vendredi 08/03</th>
                                
                                    <td colspan="12">
                                        
                                    </td>
                                
                                    <td colspan="12">
                                        
                                            <article class="tile is-child notification is-primary event">
                                                <p class="title is-size-5">Atelier cuisine</p>
                                                <p class="subtitle is-size-6">11:00 - 14:00</p>
                                            </article>
                                        
                                    </td>
                                
                                    <td colspan="24">
                                        
                                    </td>
                                
                            </tr>
                        
                            <tr>
                                <th>
                                    
                                </th>
                                
                                    <td colspan="16">
                                        
                                    </td>
                                
                                    <td colspan="8">
                                        
                                            <article class="tile is-child notification is-primaryevent">
                                                <p class="title is-size-5">Atelier couture</p>
                                                <p class="subtitle is-size-6">12:00 - 14:00</p>
                                            </article>
                                        
                                    </td>
                                
                                    <td colspan="24">
                                        
                                    </td>
                            </tr>
                </tbody>
            </table>
        </section>
    </body>
</html>
+0 -0

Update : j’ai finalement trouvé une solution satisfaisante ! :)

Elle permet d’avoir un rendu correct et homogène entre la version "grand écran" et la version mobile, et ne nécessite que peu de CSS (et pas du tout de Javascript). Voilà le code utilisé.

Exemple de données transmises au template :

{
    'data': [
        (datetime.date(2019, 3, 4), 'Lundi', [[(datetime.time(8, 0), datetime.time(12, 0), None), (datetime.time(12, 0), datetime.time(14, 0), <Event: Pique-nique collectif (04/03/2019 : 12:00 - 14:00)>), (datetime.time(14, 0), datetime.time(18, 0), None), (datetime.time(18, 0), datetime.time(20, 0), <Event: Réunion d'auto-gestion (04/03/2019 : 18:00 - 20:00)>)]]),
        (datetime.date(2019, 3, 5), 'Mardi', [[(datetime.time(8, 0), datetime.time(12, 0), None), (datetime.time(12, 0), datetime.time(14, 0), <Event: Pique-nique collectif (05/03/2019 : 12:00 - 14:00)>), (datetime.time(14, 0), datetime.time(18, 0), None), (datetime.time(18, 0), datetime.time(20, 0), <Event: Ciné-débat (05/03/2019 : 18:00 - 20:00)>)]]),
        (datetime.date(2019, 3, 6), 'Mercredi', [(datetime.time(8, 0), datetime.time(20, 0), None)]),
        (datetime.date(2019, 3, 7), 'Jeudi', [(datetime.time(8, 0), datetime.time(20, 0), None)]),
        (datetime.date(2019, 3, 8), 'Vendredi', [[(datetime.time(8, 0), datetime.time(11, 0), None), (datetime.time(11, 0), datetime.time(14, 0), <Event: Atelier cuisine (08/03/2019 : 11:00 - 14:00)>), (datetime.time(14, 0), datetime.time(20, 0), None)], [(datetime.time(8, 0), datetime.time(12, 0), None), (datetime.time(12, 0), datetime.time(14, 0), <Event: Atelier couture (08/03/2019 : 12:00 - 14:00)>), (datetime.time(14, 0), datetime.time(20, 0), None)]])
    ],
    'th_cols': ['08:00', '', '', '', '09:00', '', '', '', '10:00', '', '', '', '11:00', '', '', '', '12:00', '', '', '', '13:00', '', '', '', '14:00', '', '', '', '15:00', '', '', '', '16:00', '', '', '', '17:00', '', '', '', '18:00', '', '', '', '19:00', '', '', '', '20:00'],
    'week_dates': [
        datetime.date(2019, 3, 4), datetime.date(2019, 3, 5), datetime.date(2019, 3, 6), datetime.date(2019, 3, 7), datetime.date(2019, 3, 8), datetime.date(2019, 3, 9), datetime.date(2019, 3, 10)
    ]
}
<style>
    .event {
        height: 100px;
    }
    
    th, td {
        width: 40px !important;
        padding-left: 0px !important;
        padding-right: 0px !important;
    }
    
    .th_hour {
        position: relative;
        left: -20px;
    }
    
    @media (max-width: 767px) {
        th, td {
            width: 30px !important;
            padding-left: 2px !important;
            padding-right: 2px !important;
        }
        
        .event {
            height: auto;
            padding: 10px;
        }
    }
</style>

<section class="section">
    <nav class="level">
        <div class="level-item">
            <div class="field has-addons">
                <p class="control">
                    <a class="button">
                        <span class="icon"><i class="fas fa-chevron-left"></i></span>
                    </a>
                </p>
                <p class="control">
                    <a class="button">
                        Semaine du {{ week_dates.0|date:"d/m" }} au {{ week_dates.6|date:"d/m" }}
                    </a>
                </p>
                <p class="control">
                    <a class="button">
                        <span class="icon"><i class="fas fa-chevron-right"></i></span>
                    </a>
                </p>
            </div>
        </div>
    </nav>
    
    <table class="table" style="overflow-x: auto; display: block; table-layout: fixed;">
        <thead>
            <tr>
                <th></th>
                {% for hour in th_cols %}
                    <th {% if hour %}class="th_hour"{% endif %}>{{ hour }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% for group in data %}
                {% for row in group.2 %}
                    <tr>
                        <th {% if forloop.first and group.2.1 %}style="border-bottom: none;"{% endif %}>
                            {% if forloop.first %}
                                {{ group.1 }} {{ group.0|date:"d/m" }}
                            {% endif %}
                        </th>
                        {% for data in row %}
                            <td colspan="{{ data|datacolspan }}">
                                {% if data.2 %}
                                    <article class="tile is-child notification is-primary event">
                                        <p class="title is-size-5">{{ data.2.title }}</p>
                                        <p class="subtitle is-size-6">{{ data.2.start|date:"H:i" }} - {{ data.2.end|date:"H:i" }}</p>
                                    </article>
                                {% endif %}
                            </td>
                        {% endfor %}
                    </tr>
                {% endfor %}
            {% endfor %}
        </tbody>
    </table>
</section>

Merci pour tout ! :)

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte