PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / admin / views / emprates / tmpl / default_services.php
vikappointments / admin / views / emprates / tmpl Last commit date
default.php 3 days ago default_services.php 3 days ago default_services_modal.php 3 days ago index.html 3 days ago
default_services.php
287 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 $currency = VAPFactory::getCurrency();
15
16 $empLayout = new JLayoutFile('blocks.card');
17
18 ?>
19
20 <div class="vap-cards-container cards-service-employees" id="cards-service-employees">
21
22 <?php
23 foreach ($this->assigned as $i => $service)
24 {
25 ?>
26 <div class="vap-card-fieldset up-to-3" id="service-employee-fieldset-<?php echo $i; ?>" data-id="<?php echo $service->id; ?>" data-id-service="<?php echo $service->id_service; ?>">
27
28 <?php
29 $displayData = array();
30
31 // reduce card size
32 $displayData['class'] = 'compress';
33
34 if ($service->global)
35 {
36 $displayData['class'] .= ' published';
37
38 $icon = 'star';
39 }
40 else
41 {
42 $icon = 'sliders-h';
43 }
44
45 // fetch primary text
46 $displayData['primary'] = $this->services[$service->id_service]->name;
47
48 // fetch secondary text
49 $displayData['secondary'] = '<span class="badge badge-info">' . $currency->format($service->rate) . '</span>'
50 . '<span class="badge badge-success">' . VikAppointments::formatMinutesToTime($service->duration + $service->sleep, false) . '</span>';
51
52 // fetch badge
53 $displayData['badge'] = '<i class="fas fa-' . $icon . '"></i>';
54
55 // fetch edit button
56 $displayData['edit'] = 'vapOpenServiceEmployeeCard(\'' . $i . '\');';
57
58 // render layout
59 echo $empLayout->render($displayData);
60 ?>
61
62 <input type="hidden" name="service_json[]" value="<?php echo $this->escape(json_encode($service)); ?>" />
63
64 </div>
65 <?php
66 }
67 ?>
68
69 <!-- ADD PLACEHOLDER -->
70
71 <div class="vap-card-fieldset up-to-3 add add-service-employee">
72 <div class="vap-card compress">
73 <i class="fas fa-plus"></i>
74 </div>
75 </div>
76
77 </div>
78
79 <div style="display:none;" id="service-employee-struct">
80
81 <?php
82 // create structure for records
83 $displayData = array();
84 $displayData['class'] = 'compress';
85 $displayData['badge'] = '<i class="fas fa-star"></i>';
86 $displayData['primary'] = '';
87 $displayData['secondary'] = '';
88 $displayData['edit'] = true;
89
90 echo $empLayout->render($displayData);
91 ?>
92
93 </div>
94
95 <?php
96 JText::script('VAPSYSTEMCONFIRMATIONMSG');
97 JText::script('VAPSHORTCUTMINUTE');
98 ?>
99
100 <script>
101 var OPTIONS_COUNT = <?php echo count($this->assigned); ?>;
102 var SELECTED_OPTION = null;
103 var SERVICES_LOOKUP = <?php echo json_encode($this->services); ?>;
104
105 jQuery(function($) {
106 // open inspector for new services
107 $('.vap-card-fieldset.add-service-employee').on('click', () => {
108 // open inspector
109 vapOpenServiceEmployeeCard();
110 });
111
112 // show the inspector
113 $('#service-employee-inspector').on('inspector.show', () => {
114 var json = [];
115
116 // fetch JSON data
117 if (SELECTED_OPTION) {
118 var fieldset = $('#' + SELECTED_OPTION);
119
120 json = fieldset.find('input[name="service_json[]"]').val();
121
122 try {
123 json = JSON.parse(json);
124 } catch (err) {
125 json = {};
126 }
127 } else {
128 // load list of already selected services
129 $('[data-id-service]').each(function() {
130 json.push(parseInt($(this).attr('data-id-service')));
131 });
132 }
133
134 if (json.id === undefined) {
135 // creating new record, hide delete button
136 $(this).find('[data-role="delete"]').hide();
137 } else {
138 // editing existing record, show delete button
139 $(this).find('[data-role="delete"]').show();
140 }
141
142 fillServiceEmployeesForm(json);
143 });
144
145 // apply the changes
146 $('#service-employee-inspector').on('inspector.save', function() {
147 if (!serValidator.validate()) {
148 return false;
149 }
150
151 var service = getServiceEmployeesData();
152
153 let fieldset;
154
155 if (SELECTED_OPTION) {
156 fieldset = $('#' + SELECTED_OPTION);
157 } else {
158 fieldset = vapAddServiceEmployeeCard(service);
159 }
160
161 // refresh card details
162 vapRefreshServiceEmployeeCard(fieldset.find('.vap-card'), service);
163
164 // save JSON data
165 fieldset.find('input[name="service_json[]"]').val(JSON.stringify(service));
166
167 // auto-close on save
168 $(this).inspector('dismiss');
169 });
170
171 /**
172 * Handle inspector hide.
173 *
174 * We need to bind the event by using a handler in order to have a lower priority,
175 * since the hook used to observe any form changes may be attached after this one.
176 */
177 $(document).on('inspector.close', '#service-employee-inspector', function() {
178 if (typeof tinyMCE !== 'undefined' && tinyMCE.activeEditor) {
179 // reset editor after closing the inspector
180 let editor = Joomla.editors.instances.service_description;
181
182 editor.setValue('');
183
184 if (editor.onSave) {
185 editor.onSave();
186 }
187
188 // flag TinyMCE editor as clean because every time we edit
189 // something and we close the inspector, the editor might
190 // prompt an alert saying if we wish to stay or leave
191 if (editor.instance && editor.instance.isNotDirty === false) {
192 editor.instance.isNotDirty = true;
193 }
194 }
195 });
196
197 // delete the record
198 $('#service-employee-inspector').on('inspector.delete', function() {
199 var fieldset = $('#' + SELECTED_OPTION);
200
201 if (fieldset.length == 0) {
202 // record not found
203 return false;
204 }
205
206 // get existing record
207 var json = fieldset.find('input[name="service_json[]"]').val();
208
209 try {
210 json = JSON.parse(json);
211 } catch (err) {
212 json = {};
213 }
214
215 if (json.id) {
216 // commit record delete
217 $('#adminForm').append('<input type="hidden" name="service_deleted[]" value="' + json.id + '" />');
218 }
219
220 // auto delete fieldset
221 fieldset.remove();
222
223 // auto-close on delete
224 $(this).inspector('dismiss');
225 });
226 });
227
228 function vapOpenServiceEmployeeCard(index) {
229 if (index !== undefined) {
230 SELECTED_OPTION = 'service-employee-fieldset-' + index;
231 } else {
232 SELECTED_OPTION = null;
233 }
234
235 jQuery('#service-employee-inspector').inspector('show');
236 }
237
238 function vapAddServiceEmployeeCard(data) {
239 let index = OPTIONS_COUNT++;
240
241 SELECTED_OPTION = 'service-employee-fieldset-' + index;
242
243 var html = jQuery('#service-employee-struct').clone().html();
244
245 html = html.replace(/{id}/, index);
246
247 jQuery(
248 '<div class="vap-card-fieldset up-to-3" id="service-employee-fieldset-' + index + '" data-id-service="' + data.id_service + '">' + html + '</div>'
249 ).insertBefore(jQuery('.vap-card-fieldset.add-service-employee').last());
250
251 // get created fieldset
252 let fieldset = jQuery('#' + SELECTED_OPTION);
253
254 fieldset.vapcard('edit', 'vapOpenServiceEmployeeCard(' + index + ')');
255
256 fieldset.append('<input type="hidden" name="service_json[]" value="" />');
257
258 return fieldset;
259 }
260
261 function vapRefreshServiceEmployeeCard(elem, data) {
262 // update badge
263 var icon;
264
265 elem.vapcard('primary', data.name);
266
267 if (parseInt(data.global) == 1) {
268 icon = 'star';
269 elem.addClass('published');
270 } else {
271 icon = 'sliders-h';
272 elem.removeClass('published');
273 }
274
275 let price = jQuery('<span class="badge badge-info"></span>')
276 .html(VAPCurrency.getInstance().format(data.rate));
277
278 let duration = jQuery('<span class="badge badge-success"></span>')
279 .html((data.duration + data.sleep) + ' ' + Joomla.JText._('VAPSHORTCUTMINUTE'));
280
281 elem.vapcard('secondary', price.add(duration));
282
283 elem.vapcard('badge', '<i class="fas fa-' + icon + '"></i>');
284 }
285
286 </script>
287