PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / trunk
LatePoint – Calendar Booking Plugin for Appointments and Events vtrunk
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 / _calendar.js
latepoint / lib / assets / javascripts / bin / admin Last commit date
_agents.js 1 year ago _calendar.js 3 months ago _chart.js 9 months ago _customers.js 1 year ago _customers_import.js 9 months ago _delete-confirm.js 1 week ago _orders.js 9 months ago _processes.js 1 year ago _razorpay_connect.js 1 month ago _steps.js 9 months ago _stripe_connect.js 1 year ago main.js 2 weeks ago updates.js 3 months ago
_calendar.js
270 lines
1 /*
2 * Copyright (c) 2023 LatePoint LLC. All rights reserved.
3 */
4
5 function latepoint_check_horizontal_calendar_scroll(){
6 if(jQuery('.daily-availability-calendar.horizontal-calendar').length){
7 if(jQuery('.daily-availability-calendar.horizontal-calendar').width() < 700){
8 jQuery('.daily-availability-calendar.horizontal-calendar').scrollLeft(jQuery('.os-day.selected').index() * jQuery('.os-day.selected').width());
9 }
10 }
11 }
12
13 function latepoint_calendar_custom_period_created(){
14 latepoint_reload_calendar_view();
15 latepoint_lightbox_close();
16 }
17
18 function latepoint_init_calendar_quick_actions(){
19 latepoint_init_input_masks(jQuery('.quick-calendar-action-settings'));
20
21 jQuery('.quick-calendar-action-day-off').on('click', function(){
22 jQuery('.quick-calendar-actions-wrapper').addClass('showing-settings');
23 jQuery('.quick-calendar-actions').hide();
24 jQuery('.quick-calendar-action-settings').removeClass('setting-slot-off').addClass('setting-day-off');
25 jQuery('.quick-calendar-action-settings input[name="blocked_period_settings[full_day_off]"]').val('yes');
26 jQuery('.quick-calendar-action-toggle.selected').removeClass('selected');
27 jQuery('.quick-calendar-action-toggle[data-period-type="full"]').addClass('selected');
28
29 return false;
30 });
31 jQuery('.quick-calendar-action-slot-off').on('click', function(){
32 jQuery('.quick-calendar-actions-wrapper').addClass('showing-settings');
33 jQuery('.quick-calendar-actions').hide();
34 jQuery('.quick-calendar-action-settings').removeClass('setting-day-off').addClass('setting-slot-off');
35 jQuery('.quick-calendar-action-settings input[name="blocked_period_settings[full_day_off]"]').val('no');
36 jQuery('.quick-calendar-action-toggle.selected').removeClass('selected');
37 jQuery('.quick-calendar-action-toggle[data-period-type="partial"]').addClass('selected');
38 return false;
39 });
40
41 jQuery('.quick-calendar-action-toggle').on('click', function(){
42 if(jQuery(this).data('period-type') === 'full'){
43 jQuery('.quick-calendar-action-day-off').trigger('click');
44 }else{
45 jQuery('.quick-calendar-action-slot-off').trigger('click');
46 }
47 return false;
48 });
49 }
50
51
52 // ==========================================
53 // URL-based calendar state persistence
54 // ==========================================
55
56 var latepoint_calendar_filter_keys = [
57 {param: 'services', name: 'calendar_settings[show_service_ids][]'},
58 {param: 'agents', name: 'calendar_settings[show_agent_ids][]'},
59 {param: 'locations', name: 'calendar_settings[show_location_ids][]'}
60 ];
61
62 var latepoint_calendar_skip_url_update = false;
63
64 function latepoint_calendar_update_url(){
65 if(latepoint_calendar_skip_url_update) return;
66
67 var $form = jQuery('form.os-calendar-settings-form');
68 if(!$form.length) return;
69
70 var params = new URLSearchParams(window.location.search);
71
72 // View
73 var view = $form.find('input[name="calendar_settings[view]"]').val();
74 if(view) params.set('view', view);
75
76 // Date
77 var date = $form.find('input[name="calendar_settings[target_date_string]"]').val();
78 if(date) params.set('date', date);
79
80 // Filter IDs — only include in URL if not all are checked (to keep URL clean)
81 latepoint_calendar_filter_keys.forEach(function(filter){
82 var $checkboxes = $form.find('input[name="' + filter.name + '"]');
83 var $checked = $checkboxes.filter(':checked');
84 if($checkboxes.length && $checked.length < $checkboxes.length){
85 var ids = [];
86 $checked.each(function(){ ids.push(jQuery(this).val()); });
87 params.set(filter.param, ids.join(','));
88 }else{
89 params.delete(filter.param);
90 }
91 });
92
93 var newUrl = window.location.pathname + '?' + params.toString();
94 window.history.replaceState({}, '', newUrl);
95 }
96
97 function latepoint_calendar_restore_from_url(){
98 var params = new URLSearchParams(window.location.search);
99 var $form = jQuery('form.os-calendar-settings-form');
100 if(!$form.length) return false;
101
102 // Only restore if any calendar params exist in URL
103 var hasCalendarParams = params.has('view') || params.has('date') || params.has('services') || params.has('agents') || params.has('locations');
104 if(!hasCalendarParams) return false;
105
106 // Restore view
107 var view = params.get('view');
108 if(view){
109 $form.find('input[name="calendar_settings[view]"]').val(view);
110 jQuery('.os-calendar-view-option.os-selected').removeClass('os-selected');
111 jQuery('.os-calendar-view-option[data-value="' + view + '"]').addClass('os-selected');
112 jQuery('.calendar-wrapper').attr('data-view', view);
113 }
114
115 // Restore date
116 var date = params.get('date');
117 if(date){
118 $form.find('input[name="calendar_settings[target_date_string]"]').val(date);
119 }
120
121 // Restore filter checkboxes
122 latepoint_calendar_filter_keys.forEach(function(filter){
123 var raw = params.get(filter.param);
124 if(raw !== null){
125 var ids = raw.split(',');
126 var $checkboxes = $form.find('input[name="' + filter.name + '"]');
127
128 $checkboxes.each(function(){
129 var $cb = jQuery(this);
130 if(ids.indexOf($cb.val()) >= 0){
131 $cb.prop('checked', true).attr('checked', 'checked');
132 }else{
133 $cb.prop('checked', false).removeAttr('checked');
134 }
135 });
136
137 // Update latecheckbox filter-value label
138 var $wrapper = $checkboxes.closest('.latecheckbox-w');
139 if($wrapper.length){
140 var total = $checkboxes.length;
141 var checked = $checkboxes.filter(':checked').length;
142 if(checked < total){
143 $wrapper.find('.latecheckbox .filter-value').text(checked);
144 }else{
145 $wrapper.find('.latecheckbox .filter-value').text('All');
146 }
147 }
148 }
149 });
150
151 return true;
152 }
153
154
155 // ==========================================
156 // Calendar initialization & reload
157 // ==========================================
158
159 function latepoint_init_calendars(){
160 latepoint_check_horizontal_calendar_scroll();
161 jQuery('.os-calendar-settings-extra .latecheckbox').lateCheckbox();
162
163
164
165 jQuery('.os-calendar-view-toggle').on('click', '.os-calendar-view-option', function(){
166 jQuery(this).closest('.os-calendar-view-toggle').find('.os-calendar-view-option.os-selected').removeClass('os-selected')
167 jQuery(this).addClass('os-selected');
168 jQuery('input[name="' + jQuery(this).closest('.os-calendar-view-toggle').data('update-element-by-name') + '"]').val(jQuery(this).data('value')).trigger('change');
169 return false;
170 });
171
172 jQuery('.calendar-settings-toggler').on('click', function(){
173 jQuery('.os-calendar-settings-form').toggleClass('show-extra-settings');
174 return false;
175 });
176
177 jQuery('.os-calendar-settings-form').on('change', 'input[name="calendar_settings[view]"]', function(){
178 jQuery(this).closest('.calendar-wrapper').attr('data-view', jQuery(this).val());
179 });
180
181 jQuery('.os-calendar-settings-form').on('change', 'select, input, .latecheckbox ', function(){
182 latepoint_reload_calendar_view();
183 });
184
185
186 jQuery('.calendar-view-wrapper').on('click', '.weekly-calendar-agent-selector', function(){
187 jQuery('.weekly-calendar-agent-selector.selected').removeClass('selected');
188 jQuery(this).addClass('selected');
189 jQuery('.os-calendar-settings-form input[name="calendar_settings[selected_agent_id]"]').val(jQuery(this).data('agent-id'));
190 jQuery('.agent-weekly-calendar.selected').removeClass('selected');
191 jQuery('.agent-weekly-calendar[data-agent-id="'+jQuery(this).data('agent-id')+'"]').addClass('selected');
192 return false;
193 });
194
195 jQuery('.calendar-view-wrapper').on('click', '.daily-calendar-action-navigation-btn', function(){
196 jQuery(this).addClass('os-loading');
197 jQuery('input[name="calendar_settings[target_date_string]"]').val(jQuery(this).data('target-date')).trigger('change');
198 return false;
199 });
200
201 jQuery('.calendar-view-wrapper').on('click', '.daily-availability-calendar .os-day', function(){
202 jQuery('.os-monthly-calendar-days-w .os-day.selected').removeClass('selected');
203 jQuery(this).addClass('selected');
204 jQuery('input[name="calendar_settings[target_date_string]"]').val(jQuery(this).data('date')).trigger('change');
205 return false;
206 });
207
208
209 jQuery('.os-calendar-today-btn').on('click', function(){
210 jQuery(this).addClass('os-loading');
211 jQuery('input[name="calendar_settings[target_date_string]"]').val(jQuery(this).data('target-date')).trigger('change');
212 return false;
213 });
214
215 jQuery('.os-calendar-prev-btn').on('click', function(){
216 jQuery(this).addClass('os-loading');
217 jQuery('input[name="calendar_settings[target_date_string]"]').val(jQuery('input[name="prev_target_date"]').val()).trigger('change');
218 return false;
219 });
220
221 jQuery('.os-calendar-next-btn').on('click', function(){
222 jQuery(this).addClass('os-loading');
223 jQuery('input[name="calendar_settings[target_date_string]"]').val(jQuery('input[name="next_target_date"]').val()).trigger('change');
224 return false;
225 });
226
227 // Restore calendar state from URL params on page load
228 if(latepoint_calendar_restore_from_url()){
229 latepoint_calendar_skip_url_update = true;
230 latepoint_reload_calendar_view();
231 latepoint_calendar_skip_url_update = false;
232 }
233
234 }
235
236 function latepoint_reload_calendar_view(){
237 let $calendar_wrapper = jQuery('.calendar-view-wrapper');
238 if(!$calendar_wrapper.length) return;
239 $calendar_wrapper.addClass('os-loading');
240
241 // Update URL with current filter state
242 latepoint_calendar_update_url();
243
244 let calendar_settings = new FormData(jQuery('form.os-calendar-settings-form')[0]);
245
246 let data = new FormData();
247 data.append('params', latepoint_formdata_to_url_encoded_string(calendar_settings));
248 data.append('action', latepoint_helper.route_action);
249 data.append('route_name', $calendar_wrapper.data('route'));
250 data.append('return_format', 'json');
251
252 jQuery.ajax({
253 type: "post",
254 dataType: "json",
255 processData: false,
256 contentType: false,
257 url: latepoint_timestamped_ajaxurl(),
258 data: data,
259 success: function (response) {
260 if (response.status === "success") {
261 $calendar_wrapper.html(response.message).removeClass('os-loading');
262 jQuery('.os-calendar-today-btn, .os-calendar-prev-btn, .os-calendar-next-btn').removeClass('os-loading');
263 jQuery('.os-current-month-label .current-month').text(response.top_date_label);
264 jQuery('.os-current-month-label .current-year').text(response.top_date_year);
265 latepoint_check_horizontal_calendar_scroll();
266 }
267 }
268 });
269
270 }