FullCalendar : chargement et mise à jour des évènements dans une base de données

Posté par seiyar81 le 7 août 2013 | Laisser un commentaire (7)

Pour faire suite au précédent article présentant le plugin FullCalendar, nous allons voir comment charger des évènements depuis une base de données pour peupler notre calendrier et ensuite comment les mettre à jour.

Nous allons pour cela mettre en place un calendrier avec affichage simple (mois/semaine/jour) sur notre page web :


<html>
<head>
<link href='fullcalendar/fullcalendar/fullcalendar.css' rel='stylesheet' />
<link href='fullcalendar/fullcalendar/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='fullcalendar/jquery/jquery.min.js'></script>
<script src='fullcalendar/jquery/jquery-ui.min.js'></script>
<script src='fullcalendar/fullcalendar/fullcalendar.js'></script>

<style>

	body {
		margin-top: 40px;
		text-align: center;
		font-size: 14px;
		font-family: "Lucida Grande",Helvetica,Arial,Verdana,sans-serif;
		}

	#calendar {
		width: 900px;
		margin: 0 auto;
		}

</style>
</head>
<body>
<div id='calendar'></div>
</body>
</html>

Côté serveur, il va nous falloir une base de données, forcément, avec une table pour stocker les évènements pouvant ressembler à ceci :



--
-- Table structure for table `event`
--

CREATE TABLE IF NOT EXISTS `event` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(55) NOT NULL,
  `start` datetime NOT NULL,
  `end` datetime DEFAULT NULL,
  `allDay` tinyint(1) DEFAULT NULL,
  `url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

On va ensuite ajouter le code Javascript pour charger et mettre à jour les évènements :


    $(document).ready(function() {
	
        function updateEvent(event,dayDelta,minuteDelta,allDay)
        {
            $.ajax({ 'url': 'ajax.php?action=update', 'type': 'POST', 
                'data': {'id':event.id, 'dayDelta': dayDelta, 'minuteDelta': minuteDelta, 'allDay': allDay},
                success: function(data) {
                    if(data.error)
                        alert(data.error);
                },
                error: function(data) {
                   alert('Une erreur est survenue.'); 
                }
            });
        }
		
				$('#calendar').fullCalendar({
            header: {
    					left: 'prev,next today',
							center: 'title',
							right: 'month,agendaWeek,agendaDay'
						},
            editable: true,
            eventSources: [
                'ajax.php?action=get'
            ],
            eventDrop: function(event,dayDelta,minuteDelta,allDay,revertFunc) {    
                if (!confirm("Valider la modification ?")) {
                    revertFunc();
                } else {
                    updateEvent(event,dayDelta,minuteDelta,allDay);
                }
            },
            eventResize: function(event,dayDelta,minuteDelta,revertFunc) {
                if (!confirm("Valider la modification ?")) {
                    revertFunc();
                } else {
                    updateEvent(event,dayDelta,minuteDelta,0);
                }
            }
		});
		
	});

On note donc que le paramètre d’initialisation eventSources indique au calendrier une (ou plusieurs) url à interroger pour charger les évènements.
Le résultat attendu étant un tableau au format JSON.
Les callbacks eventDrop et eventResize sont appellés dès qu’un évènement est modifié sur le calendrier.
Si l’utilisateur valide l’action, alors on appelle la fonction updateEvent qui enverra la requête d’update au serveur.
Les paramètres dayDelta, minuteDelta et allDay correspondent aux modifications apportées à l’évènement.

Pour fournir ce tableau c’est très simple.
On va créer une page PHP pour recevoir et traiter les requêtes AJAX :


    $dsn = 'mysql:dbname=fullcalendar;host=127.0.0.1';
    $user = 'root';
    $password = 'root';

    if(isset($_GET['action']))
    {
        switch($_GET['action'])
        {
            case 'get':
                try {
                    $db = new PDO($dsn, $user, $password);
                    
                    $sql = 'SELECT * FROM event';
                    $events = array();
                    
                    foreach ($db->query($sql) as $row) {
                        $events[] = $row;
                    }
                    
                    echo json_encode($events);
                    
                } catch (PDOException $e) {
                    echo json_encode(array('error' => 'Connection failed: ' . $e->getMessage()));
                }                
                break;
            default:
                break;
        }
    }
    

Très simple donc, on contrôle l’action reçue en paramètre, si c’est get alors on renvoit un tableau contenant les évènement stockés dans la base de données.
Un simple json_encode des évènements suffit.

Avec ce code on possède donc un calendrier affichant nos évènements.
Pour maintenant mettre à jour nos évènements en base de données, il faut juste ajouter l’action update côté serveur :


case 'update':
  try {
    $db = new PDO($dsn, $user, $password);
    
    $query = $db->query('SELECT * FROM event WHERE id = ' . $_POST['id']);
    $event = $query->fetch(PDO::FETCH_ASSOC);
    
    // Mise a jour de la date
    $diff = calculateDiff($_POST['dayDelta'], $_POST['minuteDelta']);
    
    $newStart = DateTime::createFromFormat('Y-m-d H:i:s', $event['start']);
    $newStart->modify($diff);
    
    $newEnd = DateTime::createFromFormat('Y-m-d H:i:s', $event['end']);
    $newEnd->modify($diff);
    
    $sql = 'UPDATE event SET start = "'.$newStart->format('Y-m-d H:i:s').'",
    end = "'.$newEnd->format('Y-m-d H:i:s').'",
    allDay = "'.$_POST['allDay'].'"
    WHERE id = ' . $_POST['id'];
    $row = $db->query($sql);
    
    echo json_encode(array('updated' => true));
  
  } catch (PDOException $e) {
    echo json_encode(array('error' => 'Db error : ' . $e->getMessage()));
  } catch (Exception $e) {
    echo json_encode(array('error' => $e->getMessage()));
  }       
break;

Le traitement est assez simple, on utilise la classe DateTime pour calculer les changements de dates avec sa méthode modify et deux fonctions que l’on va utiliser pour transformer les dayDelta et minuteDelta en chaîne compréhensible par DateTime :


	function pluralize($string) 
  {
      preg_match("|^([0-9]+)(.*)|",$string,$matched);
      if($matched[1] > 1) {
          return number_format($matched[1]) . $matched[2] . 's';
      }
      return $string;
  }

  function calculateDiff($dayDelta, $minuteDelta)
  {
      if($dayDelta != 'null' && $dayDelta != '0') {
          if($dayDelta < 0)
              $diff = "-".pluralize(abs(intval($dayDelta))." day");
          else if($dayDelta > 0)
              $diff = "+".pluralize(intval($dayDelta)." day");
      }
      else
          $diff = "";

			if($minuteDelta != 'null' && $minuteDelta != '0') {
          if($minuteDelta < 0)
              $diff .= "-".pluralize(abs(intval($minuteDelta))." minute");
          else
              $diff .= "+".pluralize(intval($minuteDelta)." minute");
      }
        
      return $diff;
  }

Ces fonctions vont par exemple transformer dayDelta = +2 : +30 en la chaîne "+2 days"

Et voilà on a maintenant un calendrier affichant nos propres évènements et les enregistrant en base de données.

Catégorie: Développement Web, Javascript | Laisser un commentaire (7)


7 commentaires pour “FullCalendar : chargement et mise à jour des évènements dans une base de données”

  • Exemple très intéressant, mais où mettons le code cote serveur ?

    01 case ‘update’:

  • Tous fonctionne très bien, sauf,
    1-> case ‘update’: et les fonction “pluralize” et “calculateDiff”.
    Je ne sais pas trop ou les placer dans le code ?

  • Alors le case ‘update’ est a placer après le :
    case ‘get’:

    break;

    et avant le :
    default:
    break;

    Quant aux fonctions pluralize et calculateDiff elles sont a placer quelque part dans le code de l’application, soit au début du fichier avant le if, soit dans un fichier dédié à inclure.

  • Merci seiyar81 pour les conseils, je vais tester cela demain … il est pas mal fait quand même cette exemple de code …

  • Voilà, tester, tous marche super bien …

  • Cool :) Je prendrais peut-être le temps de réorganiser l’article histoire que ce soit plus clair.

  • Bonjour, je souhaiterai faire exactement la même chose sauf que j’utilise un serveur node.js donc je souhaiterai le faire sans php et avec sqilte3 malheuresement je ne trouve pas de tuto dessus quelqu’un pourrait-il m’éclairer?

Laissez un commentaire


1 + huit =