appointment_form_calendar_opendays.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 var eventUrl = 'jsp/site/Portal.jsp?page=appointment&view=getViewAppointmentForm';
146 var defaultDate = '${date_of_display}';
147 var dayView = '${day_view}';
148 var weekView = '${week_view}';
149 var events = [
150 <#if events??>
151 <#list events as event>
152 {
153 title : <#if event.isOpen & (event.nbRemainingPlaces > 0) & (event.nbRemainingPlaces = event.nbPotentialRemainingPlaces) & ('${day_view}' == 'agendaDay' || '${week_view}' == 'agendaWeek')>'${formMessages.calendarReserveLabel}'
154 <#elseif event.isOpen & (event.nbRemainingPlaces > 0) & (event.nbPotentialRemainingPlaces > 0) & (event.nbRemainingPlaces > event.nbPotentialRemainingPlaces)>'#i18n{appointment.manageCalendarSlots.labelEdit}'
155 <#elseif event.isOpen & (event.nbRemainingPlaces > 0) & (event.nbPotentialRemainingPlaces = 0)>'#i18n{appointment.manageCalendarSlots.labelEditFull}'
156 <#elseif event.isOpen & (event.nbRemainingPlaces <= 0)>'${formMessages.calendarFullLabel}'
157 <#elseif !event.isOpen>'#i18n{appointment.manageCalendarSlots.labelClosed}'
158 <#else>''</#if>,
159 className : <#if event.isOpen & (event.nbRemainingPlaces > 0) >''
160 <#elseif event.isOpen>'slot-full'<#else>'slot-closed'</#if>,
161 start : '${event.startingDateTime}',
162 end : '${event.endingDateTime}',
163 id : '${event.idSlot}',
164 url : eventUrl + '&id_form=${event.idForm}&starting_date_time=${event.startingDateTime}&modif_date=${modifDateAppointment?c}&anchor=step3',
165 },
166 </#list>
167 </#if>
168 ];
169 var eventTitleResult = <#if formMessages?? && formMessages.calendarFullLabel??>
170 '${formMessages.calendarFullLabel}'
171 <#else>
172 'nothing'
173 </#if>;
174 $(document).ready(function() {
175 $('#calendar').fullCalendar({
176 displayEventEnd: true,
177 timeFormat: 'H:mm',
178 themeSystem: 'jquery-ui',
179 themeButtonIcons: {
180 prev: 'chevron-left',
181 next: 'chevron-right',
182 prevYear: 'fast-backward',
183 nextYear: 'fast-forward'
184 },
185 hiddenDays: hiddenDays,
186 defaultDate: defaultDate,
187 defaultView: weekView,
188 height: 'auto',
189 locale: 'fr',
190 theme: true,
191 editable: false,
192 customButtons: {
193 datePicker: {
194 themeIcon: 'calendar',
195 click: function () {
196 var $btnCustom = $('.fc-datePicker-button'); // name of custom button in the generated code
197 $btnCustom.after('<input type="text" id="hiddenDate" class="datepicker"/>');
198 $("#hiddenDate").datepicker({
199 showOn: "button",
200 autoclose: true,
201 language:'fr',
202 startDate: "today",
203 endDate: moment(endingDateOfDisplay).format('DD-MM-YYYY')
204 });
205 var $btnDatepicker = $(".ui-datepicker-trigger"); // name of the generated datepicker UI
206 //Below are required for manipulating dynamically created datepicker on custom button click
207 $("#hiddenDate").focus().hide();
208 $btnDatepicker.trigger("click"); //dynamically generated button for datepicker when clicked on input textbox
209 $btnDatepicker.hide();
210 $btnDatepicker.remove();
211 $("input.datepicker").not(":first").remove();//dynamically appended every time on custom button click
212 $("#hiddenDate").change(function () {
213 $('#calendar').fullCalendar('gotoDate', moment($("#hiddenDate").val(),'DD-MM-YYYY'));
214 });
215 }
216 }
217 },
218 // header
219 header: {
220 left: 'prev',
221 center: 'datePicker, title',
222 right: 'next'
223 },
224 columnHeaderHtml: function(mom) {
225 return mom.format('dddd') + '</br>' + mom.format('LL');
226 },
227 slotLabelFormat: 'H : mm',
228 slotLabelInterval: slotDuration,
229 slotDuration: slotDuration,
230 allDaySlot: false,
231 minTime: minTime,
232 maxTime: maxTime,
233 businessHours: {
234 start: minTime,
235 end: maxTime,
236 dow: dow
237 },
238 eventClick: function(event) {
239 if (event.title == eventTitleResult || event.title == '#i18n{appointment.manageCalendarSlots.labelClosed}'
240 || event.title == '#i18n{appointment.manageCalendarSlots.labelEditFull}') {
241 return false;
242 } else {
243 location.href = event.url;
244 }
245 },
246 events: events,
247 eventRender: function(event, element) {
248 $(element).popover({
249 container: 'body',
250 placement : 'bottom',
251 html : true,
252 trigger : 'hover',
253 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>'
254 });
255 $(element).contextmenu(function() {
256 return false;
257 });
258 },
259 viewRender: function(view, element) {
260 var minDate = moment.utc(minDateOfOpenDay);
261 var maxDate = moment.utc(maxDateOfOpenDay);
262 // Past
263 if (minDate >= view.start && minDate <= view.end || view.end <= minDate) {
264 $(".fc-prev-button").prop('disabled', true);
265 $(".fc-prev-button").addClass('fc-state-disabled');
266 $('.fc-prev-button').popover('hide');
267 } else {
268 $(".fc-prev-button").removeClass('fc-state-disabled');
269 $(".fc-prev-button").prop('disabled', false);
270 }
271 // Future
272 if (maxDate >= view.start && maxDate <= view.end || maxDate <= view.start) {
273 $(".fc-next-button").prop('disabled', true);
274 $(".fc-next-button").addClass('fc-state-disabled');
275 $('.fc-next-button').popover('hide');
276 } else {
277 $(".fc-next-button").removeClass('fc-state-disabled');
278 $(".fc-next-button").prop('disabled', false);
279 }
280 },
281 eventAfterAllRender: function(view) {
282 $('.fc-event').css('cursor', 'pointer');
283 $('.fc-next-button').attr('class', 'fc-next-button btn btn-primary btn-sm');
284 $('.fc-prev-button').attr('class', 'fc-prev-button btn btn-primary btn-sm');
285 $('.fc-datePicker-button').attr('class', 'fc-datePicker-button btn btn-primary btn-sm');
286 $('.fc-datePicker-button').popover({
287 placement : 'bottom',
288 trigger : 'hover',
289 content : '#i18n{appointment.appointmentApp.calendar}'
290 });
291 $('.fc-next-button').popover({
292 placement : 'bottom',
293 trigger : 'hover',
294 content : function() {
295 var message = '#i18n{appointment.appointmentApp.nextWeek}';
296 if ($(window).width() < 1050){
297 message = '#i18n{appointment.appointmentApp.nextDay}'
298 }
299 return message;
300 }
301 });
302 $('.fc-prev-button').popover({
303 placement : 'bottom',
304 trigger : 'hover',
305 content : function() {
306 var message = '#i18n{appointment.appointmentApp.previousWeek}';
307 if ($(window).width() < 1050){
308 message = '#i18n{appointment.appointmentApp.previousDay}'
309 }
310 return message;
311 }
312 });
313 },
314 windowResize: function(view) {
315 if ($(window).width() < 1050){
316 $('#calendar').fullCalendar( 'changeView', dayView );
317 } else {
318 $('#calendar').fullCalendar( 'changeView', weekView );
319 }
320 },
321 });
322 });
323 </script>