PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.1.8
LatePoint – Calendar Booking Plugin for Appointments and Events v5.1.8
5.6.7 5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / assets / javascripts / bin / admin / _steps.js
latepoint / lib / assets / javascripts / bin / admin Last commit date
_agents.js 1 year ago _calendar.js 1 year ago _chart.js 1 year ago _customers.js 1 year ago _orders.js 1 year ago _processes.js 1 year ago _steps.js 1 year ago _stripe_connect.js 1 year ago main.js 1 year ago updates.js 1 year ago
_steps.js
428 lines
1 /*
2 * Copyright (c) 2024 LatePoint LLC. All rights reserved.
3 */
4
5
6 function latepoint_preview_init_step_category_items(step_code){
7 jQuery('.booking-form-preview .os-item-category-info').on('click', function(){
8 var $booking_form_element = jQuery(this).closest('.booking-form-preview');
9 jQuery(this).closest('.latepoint-step-content').addClass('selecting-item-category');
10 var $category_wrapper = jQuery(this).closest('.os-item-category-w');
11 var $main_parent = jQuery(this).closest('.os-item-categories-main-parent');
12 if($category_wrapper.hasClass('selected')){
13 $category_wrapper.removeClass('selected');
14 if($category_wrapper.parent().closest('.os-item-category-w').length){
15 $category_wrapper.parent().closest('.os-item-category-w').addClass('selected');
16 }else{
17 $main_parent.removeClass('show-selected-only');
18 }
19 }else{
20 $main_parent.find('.os-item-category-w.selected').removeClass('selected');
21 $main_parent.addClass('show-selected-only');
22 $category_wrapper.addClass('selected');
23 }
24 return false;
25 });
26 }
27
28 function latepoint_booking_form_discard_changes(){
29
30 let form_data = new FormData(jQuery('.booking-form-preview-settings')[0]);
31
32 var data = {
33 action: latepoint_helper.route_action,
34 route_name: jQuery('.booking-form-preview-settings').data('route-name'),
35 params: latepoint_formdata_to_url_encoded_string(form_data),
36 layout: 'none',
37 return_format: 'json'
38 }
39
40 jQuery.ajax({
41 type : "post",
42 dataType : "json",
43 url : latepoint_timestamped_ajaxurl(),
44 data : data,
45 success: function(data){
46 if(data.status === "success"){
47 jQuery('.booking-form-preview-inner').html(data.booking_form_html);
48 latepoint_init_booking_form_preview();
49 }else{
50 latepoint_add_notification(data.message, 'error');
51 }
52 }
53 });
54 }
55
56 function latepoint_booking_form_save_changes(){
57
58 let form_data = new FormData(jQuery('.booking-form-preview-settings')[0]);
59
60 jQuery('.editable-setting').each(function(){
61 form_data.set('steps_settings' + jQuery(this).data('setting-key'), jQuery(this).html());
62 });
63
64
65 form_data.set('steps_settings' + jQuery('.bf-side-media-picker-trigger').find('.os-image-id-holder').prop('name'), jQuery('.bf-side-media-picker-trigger').find('.os-image-id-holder').val());
66
67
68 var data = {
69 action: latepoint_helper.route_action,
70 route_name: jQuery('.booking-form-preview-settings').data('route-name'),
71 params: latepoint_formdata_to_url_encoded_string(form_data),
72 layout: 'none',
73 return_format: 'json'
74 }
75
76 jQuery.ajax({
77 type : "post",
78 dataType : "json",
79 url : latepoint_timestamped_ajaxurl(),
80 data : data,
81 success: function(data){
82 jQuery('.booking-form-preview-settings').removeClass('os-loading');
83 if(data.status === "success"){
84 jQuery('.bf-preview-step-settings').html(data.step_settings_html);
85 jQuery('.booking-form-preview-inner').html(data.booking_form_html);
86 jQuery('#latepoint-main-admin-inline-css').html(data.css_variables);
87 latepoint_init_booking_form_preview();
88 }else{
89 latepoint_add_notification(data.message, 'error');
90 }
91 }
92 });
93 }
94
95 function latepoint_init_booking_form_preview(){
96
97 latepoint_preview_init_step_category_items();
98 latepoint_booking_form_preview_init_datepicker();
99
100
101 jQuery('.booking-form-preview-wrapper').on('click', '.os-step-tab', function(){
102 jQuery(this).closest('.os-step-tabs').find('.os-step-tab').removeClass('active');
103 jQuery(this).addClass('active');
104 var target = jQuery(this).data('target');
105 jQuery(this).closest('.os-step-tabs-w').find('.os-step-tab-content').hide();
106 jQuery(target).show();
107 });
108
109
110 jQuery('.bf-save-btn').on('click', function(){
111 jQuery(this).addClass('os-loading');
112 latepoint_booking_form_save_changes();
113 return false;
114 });
115
116 jQuery('.bf-cancel-save-btn').on('click', function(){
117 jQuery(this).addClass('os-loading');
118 latepoint_booking_form_discard_changes();
119 return false;
120 });
121
122
123 jQuery('.booking-form-preview .bf-next-btn').on('click', function(){
124 jQuery(this).addClass('os-loading');
125 jQuery("#selected_step_code > option:selected")
126 .prop("selected", false)
127 .next()
128 .prop("selected", true).trigger('change');
129 });
130
131 jQuery('.booking-form-preview .bf-prev-btn').on('click', function(){
132 jQuery(this).addClass('os-loading');
133 jQuery("#selected_step_code > option:selected")
134 .prop("selected", false)
135 .prev()
136 .prop("selected", true).trigger('change');
137 });
138
139
140 jQuery('.booking-form-preview .os-image-selector-trigger').on('click', function(){
141 jQuery('.booking-form-preview').addClass('has-changes');
142 });
143
144 jQuery('.booking-form-preview .editable-setting').on('focus', function(){
145 jQuery('.booking-form-preview').addClass('has-changes');
146 });
147
148
149 let editor = new MediumEditor('.booking-form-preview .os-editable', {toolbar: {
150 buttons: [
151 {
152 name: 'bold',
153 classList: ['latepoint-icon', 'latepoint-icon-format_bold'],
154 },
155 {
156 name: 'anchor',
157 classList: ['latepoint-icon', 'latepoint-icon-format_link'],
158 },
159 {
160 name: 'h3',
161 classList: ['latepoint-icon', 'latepoint-icon-format_h3'],
162 },
163 {
164 name: 'h4',
165 classList: ['latepoint-icon', 'latepoint-icon-format_h4'],
166 },
167 {
168 name: 'h5',
169 classList: ['latepoint-icon', 'latepoint-icon-format_h5'],
170 },
171
172 ]
173 }
174 });
175 let editor_basic = new MediumEditor('.booking-form-preview .os-editable-basic', {toolbar: {
176 buttons: [
177 {
178 name: 'bold',
179 classList: ['latepoint-icon', 'latepoint-icon-format_bold'],
180 },
181 {
182 name: 'italic',
183 classList: ['latepoint-icon', 'latepoint-icon-format_italic'],
184 },
185 {
186 name: 'underline',
187 classList: ['latepoint-icon', 'latepoint-icon-format_underlined'],
188 },
189 {
190 name: 'anchor',
191 classList: ['latepoint-icon', 'latepoint-icon-format_link'],
192 },
193
194 ]
195 }
196 });
197 }
198
199 function latepoint_reload_booking_form_preview(){
200 latepoint_booking_form_save_changes();
201 }
202
203 function latepoint_init_steps_settings(){
204
205 jQuery('.booking-form-preview-settings').on('change', ' select, input[type="hidden"]', function(){
206 jQuery('.booking-form-preview-settings').addClass('os-loading');
207 latepoint_reload_booking_form_preview();
208 });
209
210 jQuery('.trigger-custom-color-save').on('click', function(){
211 jQuery('.booking-form-preview-settings').addClass('os-loading');
212 latepoint_booking_form_save_changes();
213 return false;
214 });
215
216 jQuery('.bf-color-scheme-color-trigger').on('click', function(){
217 jQuery('.bf-color-scheme-color-trigger.is-selected').removeClass('is-selected');
218 jQuery(this).addClass('is-selected');
219 let color_scheme = jQuery(this).data('color-code');
220 jQuery('.os-color-scheme-selector-wrapper select').val(color_scheme).trigger('change');
221 if(color_scheme == 'custom'){
222 jQuery('.os-custom-color-selector-wrapper').removeClass('is-hidden');
223 }else{
224 jQuery('.os-custom-color-selector-wrapper').addClass('is-hidden');
225 }
226 return false;
227 });
228
229 jQuery('.os-section-collapsible-trigger').on('click', function(){
230 jQuery(this).closest('.os-section-collapsible-wrapper').toggleClass('is-open');
231 return false;
232 })
233 }
234
235
236 function latepoint_booking_form_preview_init_timeslots($booking_form_element = false){
237 if(!$booking_form_element) return;
238 $booking_form_element.on('click', '.dp-timepicker-trigger', function(){
239 if(jQuery(this).hasClass('is-booked') || jQuery(this).hasClass('is-off')){
240 // Show error message that you cant select a booked period
241 }else{
242 if(jQuery(this).hasClass('selected')){
243 jQuery(this).removeClass('selected');
244 jQuery(this).find('.dp-success-label').remove();
245 }else{
246 $booking_form_element.find('.dp-timepicker-trigger.selected').removeClass('selected').find('.dp-success-label').remove();
247 var selected_timeslot_time = jQuery(this).find('.dp-label-time').html();
248 jQuery(this).addClass('selected').find('.dp-label').prepend('<span class="dp-success-label">' + latepoint_helper.datepicker_timeslot_selected_label + '</span>');
249
250 var minutes = parseInt(jQuery(this).data('minutes'));
251 var start_date = new Date($booking_form_element.find('.os-day.selected').data('date'));
252 $booking_form_element.find('.latepoint_start_date').val(start_date.toISOString().split('T')[0])
253 latepoint_trigger_next_btn($booking_form_element);
254 }
255 }
256 return false;
257 });
258 }
259
260
261 function latepoint_booking_form_preview_day_timeslots($day){
262 let $wrapper_element = jQuery('.booking-form-preview');
263 $day.addClass('selected');
264
265 var service_duration = $day.data('service-duration');
266 var interval = $day.data('interval');
267 var work_start_minutes = $day.data('work-start-time');
268 var work_end_minutes = $day.data('work-end-time');
269 var total_work_minutes = $day.data('total-work-minutes');
270 var bookable_minutes = [];
271 var available_capacities_of_bookable_minute = [];
272 if($day.attr('data-bookable-minutes')){
273 if($day.data('bookable-minutes').toString().indexOf(':') > -1){
274 // has capacity information embedded into bookable minutes string
275 let bookable_minutes_with_capacity = $day.data('bookable-minutes').toString().split(',');
276 for(let i = 0; i < bookable_minutes_with_capacity.length; i++){
277 bookable_minutes.push(parseInt(bookable_minutes_with_capacity[i].split(':')[0]));
278 available_capacities_of_bookable_minute.push(parseInt(bookable_minutes_with_capacity[i].split(':')[1]));
279 }
280 }else{
281 bookable_minutes = $day.data('bookable-minutes').toString().split(',').map(Number);
282 }
283 }
284 var work_minutes = $day.data('work-minutes').toString().split(',').map(Number);
285
286 var $timeslots = $wrapper_element.find('.timeslots');
287 $timeslots.html('');
288
289 if(total_work_minutes > 0 && bookable_minutes.length && work_minutes.length){
290 var prev_minutes = false;
291 work_minutes.forEach(function(current_minutes){
292 var ampm = latepoint_am_or_pm(current_minutes);
293
294 var timeslot_class = 'dp-timepicker-trigger';
295 var timeslot_available_capacity = 0;
296 if($wrapper_element.find('.os-dates-w').data('time-pick-style') == 'timeline'){
297 timeslot_class+= ' dp-timeslot';
298 }else{
299 timeslot_class+= ' dp-timebox';
300 }
301
302 if(prev_minutes !== false && ((current_minutes - prev_minutes) > service_duration)){
303 // show interval that is off between two work periods
304 var off_label = latepoint_minutes_to_hours_and_minutes(prev_minutes + service_duration)+' '+ latepoint_am_or_pm(prev_minutes + service_duration) + ' - ' + latepoint_minutes_to_hours_and_minutes(current_minutes)+' '+latepoint_am_or_pm(current_minutes);
305 var off_width = (((current_minutes - prev_minutes - service_duration) / total_work_minutes) * 100);
306 $timeslots.append('<div class="'+ timeslot_class +' is-off" style="max-width:'+ off_width +'%; width:'+ off_width +'%"><span class="dp-label">' + off_label + '</span></div>');
307 }
308
309 if(!bookable_minutes.includes(current_minutes)){
310 timeslot_class+= ' is-booked';
311 }else{
312 if(available_capacities_of_bookable_minute.length) timeslot_available_capacity = available_capacities_of_bookable_minute[bookable_minutes.indexOf(current_minutes)];
313 }
314 var tick_html = '';
315 var capacity_label = '';
316 var capacity_label_html = '';
317 var capacity_internal_label_html = '';
318
319 if(((current_minutes % 60) == 0) || (interval >= 60)){
320 timeslot_class+= ' with-tick';
321 tick_html = '<span class="dp-tick"><strong>'+latepoint_minutes_to_hours_preferably(current_minutes)+'</strong>'+' '+ampm+'</span>';
322 }
323 var timeslot_label = latepoint_minutes_to_hours_and_minutes(current_minutes)+' '+ampm;
324 if(latepoint_show_booking_end_time()){
325 var end_minutes = current_minutes + service_duration;
326 if(end_minutes > 1440) end_minutes = end_minutes - 1440;
327 var end_minutes_ampm = latepoint_am_or_pm(end_minutes);
328 timeslot_label+= ' - <span class="dp-label-end-time">' + latepoint_minutes_to_hours_and_minutes(end_minutes)+' '+end_minutes_ampm + '</span>';
329 }
330 if(timeslot_available_capacity){
331 var spaces_message = timeslot_available_capacity > 1 ? latepoint_helper.many_spaces_message : latepoint_helper.single_space_message;
332 capacity_label = timeslot_available_capacity + ' ' + spaces_message;
333 capacity_label_html = '<span class="dp-capacity">' + capacity_label + '</span>';
334 capacity_internal_label_html = '<span class="dp-label-capacity">' + capacity_label + '</span>';
335 }
336 timeslot_label = timeslot_label.trim();
337 $timeslots.removeClass('slots-not-available').append('<div class="'+timeslot_class+'" data-minutes="' + current_minutes + '"><span class="dp-label">' + capacity_internal_label_html + '<span class="dp-label-time">' + timeslot_label + '</span>' +'</span>'+tick_html+ capacity_label_html + '</div>');
338 prev_minutes = current_minutes;
339 });
340 }else{
341 // No working hours this day
342 $timeslots.addClass('slots-not-available').append('<div class="not-working-message">' + latepoint_helper.msg_not_available + "</div>");
343 }
344 jQuery('.times-header-label span').text($day.data('nice-date'));
345 $wrapper_element.find('.time-selector-w').slideDown(200);
346 }
347
348 function latepoint_booking_form_preview_init_monthly_calendar_navigation($booking_form_element){
349
350 if(!$booking_form_element) return;
351 $booking_form_element.on('click', '.os-month-next-btn', function(){
352 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
353 var next_month_route_name = jQuery(this).data('route');
354 if($booking_form_element.find('.os-monthly-calendar-days-w.active + .os-monthly-calendar-days-w').length){
355 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').next('.os-monthly-calendar-days-w').addClass('active');
356 latepoint_booking_form_preview_calendar_set_month_label($booking_form_element);
357 }else{
358 alert('Disabled in preview');
359 }
360 latepoint_calendar_show_or_hide_prev_next_buttons($booking_form_element);
361 return false;
362 });
363 $booking_form_element.on('click', '.os-month-prev-btn', function(){
364 var $booking_form_element = jQuery(this).closest('.latepoint-booking-form-element');
365 if($booking_form_element.find('.os-monthly-calendar-days-w.active').prev('.os-monthly-calendar-days-w').length){
366 $booking_form_element.find('.os-monthly-calendar-days-w.active').removeClass('active').prev('.os-monthly-calendar-days-w').addClass('active');
367 latepoint_booking_form_preview_calendar_set_month_label($booking_form_element);
368 }
369 return false;
370 });
371 }
372
373
374 function latepoint_booking_form_preview_calendar_set_month_label(){
375 jQuery('.os-current-month-label .current-month').text(jQuery('.os-monthly-calendar-days-w.active').data('calendar-month-label'));
376 jQuery('.os-current-month-label .current-year').text(jQuery('.os-monthly-calendar-days-w.active').data('calendar-year'));
377 }
378
379
380
381 function latepoint_booking_form_preview_init_datepicker(){
382 let $booking_form_element = jQuery('.latepoint-booking-form-element');
383 latepoint_booking_form_preview_init_timeslots($booking_form_element);
384 latepoint_booking_form_preview_init_monthly_calendar_navigation($booking_form_element);
385 $booking_form_element.on('click', '.os-months .os-day', function(){
386 if(jQuery(this).hasClass('os-day-passed')) return false;
387 if(jQuery(this).hasClass('os-not-in-allowed-period')) return false;
388 if(jQuery(this).hasClass('os-month-prev')) return false;
389 if(jQuery(this).hasClass('os-month-next')) return false;
390 if(jQuery(this).closest('.os-monthly-calendar-days-w').hasClass('hide-if-single-slot')){
391
392 // HIDE TIMESLOT IF ONLY ONE TIMEPOINT
393 if(jQuery(this).hasClass('os-not-available')){
394 // clicked on a day that has no available timeslots
395 // do nothing
396 }else{
397 $booking_form_element.find('.os-day.selected').removeClass('selected');
398 jQuery(this).addClass('selected');
399 // set date
400 $booking_form_element.find('.latepoint_start_date').val(jQuery(this).data('date'));
401 if(jQuery(this).hasClass('os-one-slot-only')){
402 // clicked on a day that has only one slot available
403 var bookable_minutes = jQuery(this).data('bookable-minutes').toString().split(':')[0];
404 var selected_timeslot_time = latepoint_format_minutes_to_time(Number(bookable_minutes), Number(jQuery(this).data('service-duration')));
405 $booking_form_element.find('.time-selector-w').slideUp(200);
406 }else{
407 // regular day with more than 1 timeslots available
408 // build timeslots
409 latepoint_booking_form_preview_day_timeslots(jQuery(this));
410 // clear time and hide next btn
411 }
412 }
413 }else{
414 // SHOW TIMESLOTS EVEN IF ONLY ONE TIMEPOINT
415 $booking_form_element.find('.latepoint_start_date').val(jQuery(this).data('date'));
416 $booking_form_element.find('.os-day.selected').removeClass('selected');
417 jQuery(this).addClass('selected');
418
419 // build timeslots
420 latepoint_booking_form_preview_day_timeslots(jQuery(this));
421 // clear time and hide next btn
422 }
423
424
425 return false;
426 });
427 }
428