Bonjour,
Mon but est d'afficher la durée de réservation pour chacun des appareils dans une timeline : appareil, début et fin réservation.
Actuellement, ma timeline indique les "resources" et "events" inscrits en "dur" dans calendar.html.twig. Je souhaite que cette timeline se mette à jour pour chaque appareil au fur et à mesure des réservations faites par les utilisateurs
j'ai installé calendar-bundle et fullcalendar scheduler. Tout fonctionne sauf timeline.
Mon fichier CalendarListener.php:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 <?php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass="App\Repository\BookingRepository") */ class Booking { /** * @ORM\Id() * @ORM\GeneratedValue() * @ORM\Column(type="integer") */ private $id; public function getId(): ?int { return $this->id; } /** * @ORM\Column(type="datetime") */ private $beginAt; /** * @ORM\Column(type="datetime", nullable=true) */ private $endAt = null; /** * @ORM\Column(type="string", length=255) */ private $title; /** * @var \User * * @ORM\ManyToOne(targetEntity="User") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="User", referencedColumnName="id") * }) */ private $user; /** * @var \Ficheavion * * @ORM\ManyToOne(targetEntity="Ficheavion") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="Avion", referencedColumnName="id") * }) */ private $avion; /** * @var \Instructeur * * @ORM\ManyToOne(targetEntity="Instructeur") * @ORM\JoinColumns({ * @ORM\JoinColumn(name="Instructeur", referencedColumnName="id") * }) */ private $instructeur; public function getBeginAt(): ?\DateTimeInterface { return $this->beginAt; } public function setBeginAt(\DateTimeInterface $beginAt): self { $this->beginAt = $beginAt; return $this; } public function getEndAt(): ?\DateTimeInterface { return $this->endAt; } public function setEndAt(?\DateTimeInterface $endAt = null): self { $this->endAt = $endAt; return $this; } public function getTitle(): ?string { return $this->title; } public function setTitle(string $title): self { $this->title = $title; return $this; } public function getUser(): ?User { return $this->user; } public function setUser(?User $user): self { $this->user = $user; return $this; } public function getAvion(): ?Ficheavion { return $this->avion; } public function setAvion(?Ficheavion $avion): self { $this->avion = $avion; return $this; } public function getInstructeur(): ?Instructeur { return $this->instructeur; } public function setInstructeur(?Instructeur $instructeur): self { $this->instructeur = $instructeur; return $this; } }
Mon fichier BookingRepository.php:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 <?php namespace App\EventListener; use App\Entity\Booking; use App\Repository\BookingRepository; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use CalendarBundle\Entity\Event; use CalendarBundle\Event\CalendarEvent; class CalendarListener { private $bookingRepository; private $router; public function __construct( BookingRepository $bookingRepository, UrlGeneratorInterface $router ) { $this->bookingRepository = $bookingRepository; $this->router = $router; } public function load(CalendarEvent $calendar): void { $start = $calendar->getStart(); $end = $calendar->getEnd(); $filters = $calendar->getFilters(); $bookings = $this->bookingRepository->findReservations($start, $end); foreach ($bookings as $booking) { // this create the events with your data (here booking data) to fill calendar $bookingEvent = new Event( $booking->getTitle(), $booking->getBeginAt(), $booking->getEndAt() // If the end date is null or not defined, a all day event is created. ) ; /* * Add custom options to events * * For more information see: https://fullcalendar.io/docs/event-object * and: https://github.com/fullcalendar/fullcalendar/blob/master/src/core/options.ts */ $bookingEvent->setOptions([ 'backgroundColor' => 'red', 'borderColor' => 'red', 'textColor'=>'yellow', ]); $bookingEvent->addOption( 'url', $this->router->generate('booking_show', [ 'id' => $booking->getId(), ]) ); // finally, add the event to the CalendarEvent to fill the calendar $calendar->addEvent($bookingEvent); }; } }
Ma vue finale calendar.html.twig:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 <?php namespace App\Repository; use App\Entity\Booking; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Symfony\Bridge\Doctrine\RegistryInterface; use Doctrine\ORM\QueryBuilder; /** * @method Booking|null find($id, $lockMode = null, $lockVersion = null) * @method Booking|null findOneBy(array $criteria, array $orderBy = null) * @method Booking[] findAll() * @method Booking[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ class BookingRepository extends ServiceEntityRepository { public function __construct(RegistryInterface $registry) { parent::__construct($registry, Booking::class); } public function whereCurrentYear(QueryBuilder $qb) { $qb ->andWhere('b.beginAt BETWEEN :start AND :end') ->setParameter('start', new \Datetime(date('Y').'-08-01')) // Date entre le 1er janvier de cette année ->setParameter('end', new \Datetime(date('Y').'-08-31')) // Et le 31 décembre de cette année ; } /** * @return Booking */ public function findReservations($start, $end){ return $this->createQueryBuilder('b') ->where('b.beginAt BETWEEN :start and :end') ->setParameter('start', $start->format('Y-m-d H:i:s') ) ->setParameter('end', $end->format('Y-m-d H:i:s') ) #->andWhere('b.avion = :type') #->setParameter('type' , 'DA 40') ->getQuery() ->getResult() ; } /* public function findByExampleField($value) { return $this->createQueryBuilder('b') ->andWhere('b.exampleField = :val') ->setParameter('val', $value) ->orderBy('b.id', 'ASC') ->setMaxResults(10) ->getQuery() ->getResult() ; } */ /* public function findOneBySomeField($value): ?Booking { return $this->createQueryBuilder('b') ->andWhere('b.exampleField = :val') ->setParameter('val', $value) ->getQuery() ->getOneOrNullResult() ; } */ }
Code twig : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 {% extends 'layout.html.twig' %} {% block body%} <a href="{{ path('booking_new') }}">Nouvelle Réservation</a> {% include '@Calendar/calendar.html' %} {% endblock %} {% block stylesheets %} <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/core/main.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/timeline/main.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/resource-timeline/main.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/interaction/main.css') }} "/> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/daygrid/main.css') }} "/> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/timegrid/main.css') }}" /> <link rel="stylesheet" type="text/css" href="{{ asset('fullcalendar/packages/list/main.css') }} "/> <script src="{{ asset('fullcalendar/packages/core/locales/fr.js') }}"></script> <script src="{{ asset('fullcalendar/packages/core/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/interaction/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/timeline/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/resource-common/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/resource-timeline/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/daygrid/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/timegrid/main.js') }}"></script> <script src="{{ asset('fullcalendar/packages/list/main.js') }}"></script> {% endblock %} {% block javascripts %} <script type="text/javascript" > document.addEventListener('DOMContentLoaded', function() { var Calendar = FullCalendar.Calendar; /* initialize the calendar -----------------------------------------------------------------*/ var calendarEl = document.getElementById('calendar-holder'); var calendar = new FullCalendar.Calendar(calendarEl, { schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source', plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list', 'resourceTimeline' ], defaultDate: new Date(), locale: 'fr', timeZone: 'Europe/Paris', minTime: '06:00:00', maxTime: '19:00:00', editable: true, // enable draggable events droppable: true, // this allows things to be dropped onto the calendar selectable: true, eventLimit: true, // allow "more" link when too many events aspectRatio: 1.8, scrollTime: '00:00', // undo default 6am scrollTime defaultView: 'resourceTimelineDay', slotDuration: '00:15:00', header: { left: 'today prev,next', center: 'title', right: 'resourceTimelineDay,timeGridWeek,dayGridMonth,listWeek, timelineDay', }, resourceLabelText: 'Appareils', resources: [ { id: 'a', title: 'PA 28', eventColor: 'black'}, { id: 'b', title: 'DR 400', eventColor: 'green' }, { id: 'c', title: 'DR 500', eventColor: 'red' }, { id: 'd', title: 'DA 42', eventColor: 'orange' }, { id: 'e', title: 'DR 400 DC', eventColor: 'grey' }, { id: 'f', title: 'DR 500 RF', eventColor: 'yellow' }, ], events:[ { id: '1', resourceId: 'a', start: '2019-08-07T11:00:00', end: '2019-08-07T12:00:00', title: 'PA 28' }, { id: '2', resourceId: 'b', start: '2019-08-07T08:00:00', end: '2019-08-07T09:00:00', title: 'DR 400' }, { id: '3', resourceId: 'c', start: '2019-08-07T10:30:00', end: '2019-08-07T11:30:00', title: 'DA 500' }, { id: '4', resourceId: 'd', start: '2019-08-07T14:15:00', end: '2019-08-07T15:45:00', title: 'DA 42' }, { id: '5', resourceId: 'e', start: '2019-08-07T08:45:00', end: '2019-08-07T09:45:00', title: 'DR 400 DC' }, { id: '6', resourceId: 'f', start: '2019-08-07T11:30:00', end: '2019-08-07T12:30:00', title: 'DA 500 RF' }, ], eventSources: [ { url: "{{ path('fc_load_events') }}", method: "POST", extraParams: { filters: JSON.stringify({}), }, failure: () => { alert("There was an error while fetching FullCalendar!"); }, }, ], }); //var resourceA = calendar.getResourceById('a'); //var events = resourceA.getEvents(); //var eventTitles = events.map(function(event) { return event.title }); //console.log(eventTitles); // [ 'Event 1', 'Event 2' ] //var event = calendar.getEventById('1'); //var resources = event.getResources(); //var resourceIds = resources.map(function(resource) { return resource.id }); //event.setResources([ 'a', 'b', 'c', 'd' ]); // set multiple //console.log(resourceIds); // [ 'a' ] calendar.render(); }); </script> {% endblock %}
Merci à tous ceux qui pourront m'orienter vers la solution.
PS: j'ai essayé en vain la solution indiquée dans ce post: https://www.developpez.net/forums/d1...-fullcalendar/
Partager