Changer le mois du calendrier sans recharger la page

175860
,

Bonjour tout le monde. Je travail actuellement sur un calendrier de réservation pour deux appartements. Le calendrier fonctionne correctement et affiche bien les réservations. Je précise que mon calendrier fonctionne exactement comme dans le cours présent sur le site [https://www.grafikart.fr/tutoriels/calendrier-php-partie1-995].

Mon problème est que l'intégralité de ma page recharge lorsque je passe au mois précédent/suivant. Rien de plus normal vu que mes boutons mois précédent/suivant sont des liens qui renvoient au controller les nouvelles variables mois et année afin de recréer une vue du calendrier et effectuer une requête afin de récupérer les réservations du mois affiché.

Je suppose que pour palier au problème, il faut que j'utilise AJAX. Je suis totalement perdu car que je n'ai jamais utilisé conjointement AJAX avec Symfony.

Dois-je effectuer l'intégralité du traitement de mon controller dans la requête ajax ? Comment procéder ?

Le but final étant d'intégrer ce calendrier de réservation sur un site qui est sous symfony.
Merci d'avance.

index.html.twig:

{% extends 'base.html.twig' %}

{% block body %}  

<div class="d-flex flex-row align-items-center justify-content-between mx-sm-3">
    <h1>{{ calendar.toString }}</h1> //Affiche Le mois et l'année
    <div> //Boutons pour passer au mois précédent/suivant
        <a href="{{ path('calendar', { 'month': calendar.previousMonth.month, 'year': calendar.previousMonth.year }) }}" class="btn btn-primary">&lt;</a>
        <a href="{{ path('calendar', { 'month': calendar.nextMonth.month, 'year': calendar.nextMonth.year }) }}" class="btn btn-primary">&gt;</a>
    </div>
</div>

<table class="calendar_table">

    <tr>
        {% for day in calendar.days %}
        <th>
            <div class="calendar__weekday">{{ day }}</div> //Affiche sur la première ligne du calendrier les jours de la semaine en toute lettre
        </th>
        {% endfor %}
    </tr>

    {% for i in range(0, weeks) %} //Pour chaque semaines du mois
    <tr>
        {% for day in calendar.days %} //Pour chaque jours de la semaine

            {% set date = startingDay|date_modify("+" ~ (loop.index0 + i * 7) ~ "days" ) %}
            <td {% if not calendar.withinMonth(date) %} class="calendar__othermonth" {% endif %}> //Grise les jours qui n'appartiennet pas au mois sélectionné
            <div class="calendar__day //Ajoute une classe si le jours est réservé pour l'appartement 8 ou/et 9
                {% for reservation8 in reservationsView_8 %}
                    {% if date|date('Y-m-d') >= reservation8.start|date('Y-m-d') and date|date('Y-m-d') <= reservation8.end|date('Y-m-d') %}
                        reservation_8
                    {% endif %}
                {% endfor %}
                {% for reservation9 in reservationsView_9 %}
                    {% if date|date('Y-m-d') >= reservation9.start|date('Y-m-d') and date|date('Y-m-d') <= reservation9.end|date('Y-m-d') %}
                        reservation_9
                    {% endif %}
                {% endfor %}
            ">{{ date|date("d") }}</div> //Nombre du jour
        </td>
        {% endfor %}
    </tr>
    {% endfor %}
</table>

{% endblock %}

CalendarController.php:

<?php

namespace App\Controller;

use App\Calendar\Calendar;
use App\Entity\Appartement;

use App\Entity\Reservation;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;


class CalendarController extends AbstractController
{
    /**
     * @Route("/calendar", name="calendar")
     */
    public function index(Request $request)
    {
        $getMonth = $request->query->get('month'); //Récupère le mois et l'année passés en $_post via les liens mois précédent/suivant
        $getYear = $request->query->get('year');

        $calendar = new Calendar($getMonth ?? null, $getYear ?? null); //Créer une vue du mois sélectionné. Si le controller n'a pas reçu de mois/année en paramètre, il prend le mois actuel.

        $weeks = $calendar->getWeeks(); //Nombre de semaines dans le mois

        $startingDay = $calendar->getStartingDay(); //Premier jour de la vue du mois.
        $startingDay = $startingDay->format('N') === '1' ? $startingDay : $calendar->getStartingDay()->modify('last monday'); //Si le premier jours de la vue du mois n'est pas le 1er, prend le lundi de la semaine précédente.

        $endingDay = (clone $startingDay)->modify('+' . (6 + 7 * ($weeks - 1)) . ' days'); //Dernier jours de la vue du mois

        $em = $this->getDoctrine()->getManager();
        $connection = $em->getConnection();

        $start = $startingDay->format('Y-m-d');
        $end = $endingDay->format('Y-m-d');

        $query1 = $connection->prepare("SELECT * FROM reservation r WHERE r.appartement_id = 1 AND r.start BETWEEN '$start' AND '$end'");
        $query1->execute();
        $query2 = $connection->prepare("SELECT * FROM reservation r WHERE r.appartement_id = 2 AND r.start BETWEEN '$start' AND '$end'");
        $query2->execute();
        $reservationsView_8 = $query1->fetchAll();
        $reservationsView_9 = $query2->fetchAll();

        return $this->render('calendar/index.html.twig', [
            'calendar'=> $calendar,
            'startingDay' => $startingDay,
            'weeks' => $weeks,
            'reservationsView_8' => $reservationsView_8,
            'reservationsView_9' => $reservationsView_9,
        ]);
    }
}

1 Réponse

134298
,

Il faut en effet passer par l'ajax !

Si tu utilise jQuerry tu peux le faire assez simplement de cette manière

$.ajax({
    url: '{{ path('taroute') }}',
    data: {'month':'tonmois', 'year', 'tonannee'},
    success: function(e){ // Ici e va te retourner ta template twig de ton mois et ton année passer en paramètre juste au dessus
        $('.calendar_table').replaceWith($(e).find('.calendar_table')   // Ici tu remplace le contenu de ta div par celle de la template
    }
})

A noter que si tu utilise cette technique il faudra remplacer dans ton code

$getMonth = $request->query->get('month'); //Récupère le mois et l'année passés en $_post via les liens mois précédent/suivant
$getYear = $request->query->get('year');

Parce que quand tu utiliser $request->query->get('month') tu récupérer ta valuer en GET et non en POST ($_ post) comme indiqué.
Il faudra donc que tu utilises $request->request->get('month')

J'espère que cela pourra t'aider ;)