appointment_form_list_open_slots_grouped.html
1 <link rel='stylesheet' href='css/plugins/appointment/fullcalendar.css' />
2 <link rel='stylesheet' href='css/plugins/appointment/fullcalendar_ow.css' />
3 <link rel="stylesheet" href="js/jquery/plugins/ui/css/jquery-ui.min.css" />
4 <script src='js/plugins/appointment/jquery.min.js' ></script>
5 <script src="js/plugins/appointment/moment.min.js" ></script>
6 <script src='js/plugins/appointment/fullcalendar.min.js' ></script>
7 <script src='js/plugins/appointment/locale-all.js' ></script>
8 <script src="js/plugins/appointment/bootstrap-datepicker.js" ></script>
9 <script src="js/locales/bootstrap-datepicker.fr.js" charset="utf-8"></script>
10 <link rel='stylesheet' href='css/plugins/appointment/bootstrap-datepicker.min.css' />
11 <link rel='stylesheet' href='css/plugins/appointment/bootstrap-datepicker.standalone.css' />
12 <link href="css/plugins/appointment/appointment.css" rel="stylesheet" />
13 <div class="row nextStepTitleRow">
14 <div class="col-xs-12">
15 <div class="container">
16 <h2 class="stepTitle next">
17 <span class="stepTitleNumber previous"><i class="fa fa-check"></i></span>
18 <#if form.displayTitleFo && form.title != '' >
19 ${form.title}
20 <#else>
21 #i18n{appointment.appointmentApp.defaultTitle}
22 </#if>
23 </h2>
24 </div>
25 </div>
26 </div>
27 <div class="row steps">
28 <div class="col-xs-12">
29 <div class="container recap">
30 <div class="row">
31 <div class="col-xs-12 col-sm-9 col-md-9">
32 <ul class="recap-step-list">
33 <li>${form.description!}</li>
34 </ul>
35 </div>
36 <div class="col-xs-12 col-sm-4 col-md-3 stepRecapButtonMargin">
37 </div>
38 </div>
39 </div>
40 </div>
41 </div>
42 ${mark_nb_places_to_take_form!}
43 <div class="row currentStepTitleRow">
44 <div class="col-xs-12">
45 <div class="container">
46 <h2 class="current stepTitle" id="step2">
47 <span class="current stepTitleNumber">2</span>
48 <#if formMessages.calendarTitle?? && formMessages.calendarTitle != ''>
49 ${formMessages.calendarTitle}
50 </#if>
51 </h2>
52 </div>
53 </div>
54 </div>
55 <div class="row currentStepContentRow">
56 <div class="col-xs-12">
57 <div class="container" id="current_step">
58 <div class="formGroupContainer">
59 <#if infos??>
60 <#if infos?size > 0 >
61 <div class="alert alert-info" id='messages_infos_div'>
62 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
63 <#list infos as info >
64 <span class="icon"><i class='fa fa-info-circle' /></i> ${info.message}<br />
65 </#list>
66 </div>
67 </#if>
68 </#if>
69 <#if formCalendarErrors??>
70 <#if errors?size > 0 >
71 <div class="alert alert-danger" id='messages_infos_div'>
72 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
73 <#list errors as error >
74 <span class="icon"><i class='fa fa-exclamation-circle' /></i> ${error.message}<br />
75 </#list>
76 </div>
77 </#if>
78 <#else>
79 <#if errors?size > 0 >
80 <div class="alert alert-danger" id='messages_infos_div'>
81 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
82 <#list errors as error >
83 <span class="icon"><i class='fa fa-exclamation-circle' /></i> ${error.message}<br />
84 </#list>
85 </div>
86 </#if>
87 <div id="calendar"></div>
88 </#if>
89 </div>
90 </div>
91 </div>
92 </div>
93 <div class="row nextStepTitleRow">
94 <div class="col-xs-12">
95 <div class="container">
96 <h2 class="stepTitle next">
97 <span class="stepTitleNumber next">3</span>
98 #i18n{appointment.appointmentApp.enteringInformation}
99 </h2>
100 </div>
101 </div>
102 </div>
103 <div class="row nextStepTitleRow">
104 <div class="col-xs-12">
105 <div class="container">
106 <h2 class="stepTitle next">
107 <span class="stepTitleNumber next">4</span>
108 #i18n{appointment.appointmentApp.recap.title}
109 </h2>
110 </div>
111 </div>
112 </div>
113 <div class="row nextStepTitleRow">
114 <div class="col-xs-12">
115 <div class="container">
116 <h2 class="stepTitle next">
117 <span class="stepTitleNumber next">5</span>
118 #i18n{appointment.appointmentApp.confirmation}
119 </h2>
120 </div>
121 </div>
122 </div>
123 <script type="text/javascript">
124 var slotDuration = '${min_duration}';
125 var minTime = '${min_time}';
126 var maxTime = '${max_time}';
127 var strEndingDateOfDisplay = '${str_ending_date_of_display}';
128 var endingDateOfDisplay = '${ending_date_of_display}';
129 var minDateOfOpenDay = '${min_date_of_open_day}';
130 var maxDateOfOpenDay = '${max_date_of_open_day}';
131 var dow = [
132 <#if dow??>
133 <#list dow as day>
134 ${day},
135 </#list>
136 </#if>
137 ];
138 var hiddenDays = [
139 <#if hidden_days??>
140 <#list hidden_days as hidden_day>
141 ${hidden_day},
142 </#list>
143 </#if>
144 ];
145
146 var eventUrl = 'jsp/site/Portal.jsp?page=appointment&view=getViewAppointmentForm';
147 var defaultDate = '${date_of_display}';
148 var dayView = '${day_view}';
149 var weekView = '${week_view}';
150 var events = [
151 <#if events??>
152 <#list events as event>
153 {
154 title : <#if event.isOpen & (event.nbRemainingPlaces > 0) & (event.nbRemainingPlaces = event.nbPotentialRemainingPlaces) & ('${day_view}' == 'agendaDay' || '${week_view}' == 'agendaWeek')>'${formMessages.calendarReserveLabel}'
155 <#elseif event.isOpen & (event.nbRemainingPlaces > 0) & (event.nbPotentialRemainingPlaces > 0) & (event.nbRemainingPlaces > event.nbPotentialRemainingPlaces)>'#i18n{appointment.manageCalendarSlots.labelEdit}'
156 <#elseif event.isOpen & (event.nbRemainingPlaces > 0) & (event.nbPotentialRemainingPlaces = 0)>'#i18n{appointment.manageCalendarSlots.labelEditFull}'
157 <#elseif event.isOpen & (event.nbRemainingPlaces <= 0)>'${formMessages.calendarFullLabel}'
158 <#elseif !event.isOpen>'#i18n{appointment.manageCalendarSlots.labelClosed}'
159 <#else>''</#if>,
160 className : <#if event.isOpen & (event.nbRemainingPlaces > 0) >''
161 <#elseif event.isOpen>'slot-full'<#else>'slot-closed'</#if>,
162 start : '${event.startingDateTime}',
163 end : '${event.endingDateTime}',
164 id : '${event.idSlot}',
165 url : eventUrl + '&id_form=${event.idForm}&starting_date_time=${event.startingDateTime}&modif_date=${modifDateAppointment?c}&anchor=step3',
166 },
167 </#list>
168 </#if>
169 ];
170 var eventTitleResult = <#if formMessages?? && formMessages.calendarFullLabel??>
171 '${formMessages.calendarFullLabel}'
172 <#else>
173 'nothing'
174 </#if>;
175 $(document).ready(function() {
176 $('#calendar').fullCalendar({
177 displayEventEnd: true,
178 timeFormat: 'H:mm',
179 themeSystem: 'jquery-ui',
180 themeButtonIcons: {
181 prev: 'chevron-left',
182 next: 'chevron-right',
183 prevYear: 'fast-backward',
184 nextYear: 'fast-forward'
185 },
186 hiddenDays: hiddenDays,
187 defaultDate: defaultDate,
188 defaultView: weekView,
189 height: 'auto',
190 locale: 'fr',
191 theme: true,
192 editable: false,
193 customButtons: {
194 datePicker: {
195 themeIcon: 'calendar',
196 click: function () {
197 var $btnCustom = $('.fc-datePicker-button'); // name of custom button in the generated code
198 $btnCustom.after('<input type="text" id="hiddenDate" class="datepicker"/>');
199 $("#hiddenDate").datepicker({
200 showOn: "button",
201 autoclose: true,
202 language:'fr',
203 startDate: "today",
204 endDate: moment(endingDateOfDisplay).format('DD-MM-YYYY')
205 });
206 var $btnDatepicker = $(".ui-datepicker-trigger"); // name of the generated datepicker UI
207 //Below are required for manipulating dynamically created datepicker on custom button click
208 $("#hiddenDate").focus().hide();
209 $btnDatepicker.trigger("click"); //dynamically generated button for datepicker when clicked on input textbox
210 $btnDatepicker.hide();
211 $btnDatepicker.remove();
212 $("input.datepicker").not(":first").remove();//dynamically appended every time on custom button click
213 $("#hiddenDate").change(function () {
214 $('#calendar').fullCalendar('gotoDate', moment($("#hiddenDate").val(),'DD-MM-YYYY'));
215 });
216 }
217 }
218 },
219 // header
220 header: {
221 left: 'prev',
222 center: 'datePicker, title',
223 right: 'next'
224 },
225 columnHeaderHtml: function(mom) {
226 return mom.format('dddd') + '</br>' + mom.format('LL');
227 },
228 slotLabelFormat: 'H : mm',
229 slotLabelInterval: slotDuration,
230 slotDuration: slotDuration,
231 allDaySlot: false,
232 minTime: minTime,
233 maxTime: maxTime,
234 businessHours: {
235 start: minTime,
236 end: maxTime,
237 dow: dow
238 },
239 eventClick: function(event) {
240 if (event.title == eventTitleResult || event.title == '#i18n{appointment.manageCalendarSlots.labelClosed}'
241 || event.title == '#i18n{appointment.manageCalendarSlots.labelEditFull}') {
242 return false;
243 }
244 },
245 events: events,
246 eventRender: function(event, element) {
247 $(element).popover({
248 container: 'body',
249 placement : 'bottom',
250 html : true,
251 trigger : 'hover',
252 content : '<center>'+event.start.format('ddd DD/MM')+'</center>' + '<center><b>' + event.start.format('HH:mm') + '</b> - <b>' + event.end.format('HH:mm')+'</b></center>'
253 });
254 },
255 viewRender: function(view, element) {
256 var minDate = moment.utc(minDateOfOpenDay);
257 var maxDate = moment.utc(maxDateOfOpenDay);
258 // Past
259 if (minDate >= view.start && minDate <= view.end || view.end <= minDate) {
260 $(".fc-prev-button").prop('disabled', true);
261 $(".fc-prev-button").addClass('fc-state-disabled');
262 $('.fc-prev-button').popover('hide');
263 } else {
264 $(".fc-prev-button").removeClass('fc-state-disabled');
265 $(".fc-prev-button").prop('disabled', false);
266 }
267 // Future
268 if (maxDate >= view.start && maxDate <= view.end || maxDate <= view.start) {
269 $(".fc-next-button").prop('disabled', true);
270 $(".fc-next-button").addClass('fc-state-disabled');
271 $('.fc-next-button').popover('hide');
272 } else {
273 $(".fc-next-button").removeClass('fc-state-disabled');
274 $(".fc-next-button").prop('disabled', false);
275 }
276 },
277 eventAfterAllRender: function(view) {
278 $('.fc-event').css('cursor', 'pointer');
279 $('.fc-next-button').attr('class', 'fc-next-button btn btn-primary btn-sm');
280 $('.fc-prev-button').attr('class', 'fc-prev-button btn btn-primary btn-sm');
281 $('.fc-datePicker-button').attr('class', 'fc-datePicker-button btn btn-primary btn-sm');
282 $('.fc-datePicker-button').popover({
283 placement : 'bottom',
284 trigger : 'hover',
285 content : '#i18n{appointment.appointmentApp.calendar}'
286 });
287 $('.fc-next-button').popover({
288 placement : 'bottom',
289 trigger : 'hover',
290 content : function() {
291 var message = '#i18n{appointment.appointmentApp.nextWeek}';
292 if ($(window).width() < 1050){
293 message = '#i18n{appointment.appointmentApp.nextDay}'
294 }
295 return message;
296 }
297 });
298 $('.fc-prev-button').popover({
299 placement : 'bottom',
300 trigger : 'hover',
301 content : function() {
302 var message = '#i18n{appointment.appointmentApp.previousWeek}';
303 if ($(window).width() < 1050){
304 message = '#i18n{appointment.appointmentApp.previousDay}'
305 }
306 return message;
307 }
308 });
309 },
310 windowResize: function(view) {
311 if ($(window).width() < 1050){
312 $('#calendar').fullCalendar( 'changeView', dayView );
313 } else {
314 $('#calendar').fullCalendar( 'changeView', weekView );
315 }
316 },
317 });
318 });
319 </script>