5568 sujets

Sémantique web et HTML

Hello,
Je cherche à réaliser un planning, avec en colonnes les heures (8:00, 9:00, ....) et en lignes les jours.
Le but du jeu est d'avoir des taches, sur une journée, qui peuvent prendre 1 ou plusieurs créneaux horaires contigus (de 8:00 à 10:00 par ex....)
Ces taches peuvent être déplacées à la souris, et je veux pouvoir modifier la durée de la tache à la souris.

Je ne me fais pas de souci pour tout ce qui est Ajax (déplacement, changement de durée.....)

En fait, je me demande quel est le meilleur moyen d'implémenter ça en HTML. Le tableau global avec TABLE, TR, TD ? Une suite de DIV pour chaque créneau ?
Pour les taches, a priori j'utiliserai des DIV. Mais comment gérer les taches sur plusieurs créneaux horaires ? Faire du colspan sur le tableau global ?

Merci pour vos avis éclairés Smiley cligne
Vickk
Modifié par vickk (19 May 2009 - 13:12)
Merci Laurie-Anne pour ta participation.

Et ensuite, tu me conseilles quoi ?
- De mettre les taches en DIV, à l'intérieur des cellules du tableau, en jouant sur les colspan pour les taches plus longues ?
- De faire des DIV qui seraient "par-dessus" le tableau ? (en position absolute par exemple)
- D'utiliser directement les TD (au besoin avec les colspan), sans rajouter de DIV ? (Mais est-ce seulement possible de faire de drag&drop sur du TD...)
La question n'est pas si simple puisqu'elle requiert pour chaque déplacement de cellule (td) non seulement de reconstituer les colspan (pas si fastoche) mais aussi de reconstituer l'ordonnancement logique et organique qui lie les colonnes et les rangées : les th du thead et les headers de cellules du tbody notamment.
Pour éviter de toucher à la structure de la table il serait peut-être préférable de déplacer des divs. Ça me paraît d'autant plus logique que le "fond" de la table est un croisement de dates et d'heures, et que les événements ne sont que du remplissage : ce sont donc des objets "flottants" qui doivent être alimentés, modifiés et déplacés indépendamment de la structure qui les accueille.
Merci à vous 2.
Finalement, j'ai opté pour la méthode Arsène.
J'ai mon fond en TABLE, et je place des DIV en absolute par-dessus. Je peux même les dragger tout en "collant" à la grille définie par ma table.
Salut à tous !

J'ai lu avec grand intérêt vos échanges, cherchant à faire plus ou moins la même chose actuellement pour un p'tit Intranet perso... Smiley cligne
Vickk, est-ce que tu pourrais m'en dire un peu plus sur la façon dont tu as mis en place tout ça ? Et même éventuellement nous en faire profiter ?

Merci d'avance,
Bon, j'en suis juste au prototype, hein !

Je créé une première div en position relative, qui contient le mon joli tableau. Ensuite je créé une DIV qui délimitera la zone "utile" de mes tâches (qui ne pourront donc se déplacer que dans cette zone). Et dans ce DIV de zone utile, je place mes DIV déplaçables.

Donc en gros, ça me donne ça :



<?php
  $nb_col = 15;
  $nb_lignes = 5;
  echo "<br>dhzudhzu<br>";

  echo '<div id="tableau">';
  echo '<table id="table">';
  echo '<thead><tr>';
  echo '<th>&nbsp;</th>';

  // Entete du tablea
  for ($i=0;$i<$nb_col;$i++) {
    echo '<th class="table_cell">'.($i + 8).':00</th>';
  }
  echo '</tr></thead><tbody>';
  
  // Corps du tableau
  for ($j=0;$j<$nb_lignes;$j++) {
    echo '<tr>';
    echo '<td class="table_lib" id="cell_'.$j.'_LIB">LIGNE '.$j.'</td>';
    for ($i=0;$i<$nb_col;$i++) {
      echo '<td class="table_cell" id="cell_'.$j.'_'.$i.'">'.$j.$i.'</td>';
    }
    echo '</tr>';
  }
  
  echo '</tbody>';
    
  echo '</table>';

  
  echo '<div id="draggable_zone">';
  // Creation des div flottantes
  echo '<div id="m1" class="mission" style="width:48px;height:25px;top:0px;left:0px;">M1</div>';
  echo '<div id="m2" class="mission" style="width:101px;height:25px;top:30px;left:53px;">M2</div>';
  echo '<div id="m5" class="mission" style="width:101px;height:25px;top:30px;left:159px;">M5</div>';
  echo '<div id="m3" class="mission" style="width:154px;height:25px;top:0px;left:53px;">M3</div>';
  echo '<div id="m4" class="mission" style="width:48px;height:25px;top:30px;left:0px;">M4</div>';
  echo '<div id="m6" class="mission" style="width:101px;height:25px;top:60px;left:106px;">M6</div>';

  echo '</div>'; // div draggable_zone

  echo '</div>'; // div tableau


Avec le CSS qui va bien :


#tableau {
  position: relative;
  /*border: 2px solid yellow;*/
}
#table {
  /*border: 2px solid yellow;*/
  border-collapse: collapse;
}

.table_lib{
  width: 120px;
  border: 1px solid grey;
  margin:0;
}

.table_cell{
  width: 50px;
  border: 1px solid grey;
  text-align: center;
  height: 30px;
}

#draggable_zone {
  position: absolute;
  width:793px;
  height:148px;
  top:31px;
  left:124px;
  /*border: 1px solid purple;*/
}

.mission {
  position: absolute;
  background-color: cyan;
  border: 2px solid black;
}


Bon alors mon div de zone utile, que j'ai appelé "draggable_zone", je l'ai calé exactement sur le tableau, en sautant la 1ère colonne et la ligne d'entête.

Pour son positionnement left, il faut prendre en compte la largeur de la première colonne, son border et le padding (que je n'ai pas redéfini). Pareil pour le top. Et pareil pour les DIVs déplaçables... Sauf que leur top et left sont calculés à partir du coin supérieur gauche de la "draggable_zone". Leur largeur et hauteur correspond à la taille d'une TD du tableau, tenant compte des border....

Bon, là c'était un peu du réglage à la main, mais c'est clair qu'il va falloir arranger un peu tout ça. Smiley cligne

Ensuite, pour les rendre draggable, j'ai utilisé script.aculo.us et prototype.
Par exemple, pour ma case M1 :

var drag_m1 = new Draggable('m1',{snap:[53,30],revert:true});

le snap lui permet de "coller" à la structure du tableau. Mais ce n'est pas bien : elle peut sortir de sa surface de prédilection. Il faut alors créer une nouvelle fonction "snap". Exemple, sur ma m3 :

  var drag_m3 = new Draggable('m3',{
    snap: function(x,y,draggable) {
      function constrain(n, lower, upper) {
        if (n > upper) return upper;
        else if (n < lower) return lower;
        else return n;
      }
     
      element_dimensions = Element.getDimensions(draggable.element);
      parent_dimensions = Element.getDimensions(draggable.element.parentNode);
      
      // 53 le snap horizontal - 30 le snap vertical
      var combien_x = (x/53).round();
      var combien_y = (y/30).round();
      x = combien_x * 53;
      y = combien_y * 30;
      
      
      return[
        constrain(x, 0, parent_dimensions.width - element_dimensions.width),
        constrain(y, 0, parent_dimensions.height - element_dimensions.height)];
    },
    revert:true
  });
où je recalcule d'abord la position de x et de y en fonction du pas que je m'impose (pour adhérer à la grille...) et ensuite la fonction constrain vérifie que le div reste bien à l'intérieur de son div parent, la "draggable_zone".

Bon, j'espère que ça t'a un peu avancé... Ce n'est pas propre, ce n'est pas fini, mais c'est un bon début, non ?
Modifié par vickk (19 May 2009 - 23:29)
Vraiment nickel ! Merci beaucoup ! Je te rassure, c'est très bien comme ça, ça me permet d'avoir une "base" saine pour mon projet.
Encore merci et bonne continuation à toi !