PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / views / dashboard / tmpl / default_widgets.php

default_widgets.php in VikBooking Hotel Booking Engine & PMS 1.6.4, at admin/views/dashboard/tmpl/default_widgets.php

1,172 lines 50.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 $vbo_app = VikBooking::getVboApplication();
14
15 // get admin widgets helper
16 $widgets_helper = VikBooking::getAdminWidgetsInstance();
17 $widgets_map = $widgets_helper->getWidgetsMap();
18
19 // get all widgets by preloading their assets (if any)
20 $widgets_names = $widgets_helper->getWidgetNames($preload = true);
21
22 $widgets_welcome = $widgets_helper->showWelcome();
23
24 // global permissions are necessary to customize the admin widgets
25 $vbo_auth_global = JFactory::getUser()->authorise('core.vbo.global', 'com_vikbooking');
26
27 // check if the notification audio file exists within VCM
28 $notif_audio_path = implode(DIRECTORY_SEPARATOR, [VCM_ADMIN_PATH, 'assets', 'css', 'audio', 'new_notification.mp3']);
29 $notif_audio_url = is_file($notif_audio_path) ? (VCM_ADMIN_URI . implode('/', ['assets', 'css', 'audio', 'new_notification.mp3'])) : null;
30
31 // load sortable library
32 JHtml::fetch('jquery.framework', true, true);
33 JHtml::fetch('script', VBO_SITE_URI.'resources/jquery-ui.sortable.min.js');
34
35 // load language vars for JavaScript
36 JText::script('VBO_WIDGETS_WELCOME');
37 JText::script('VBO_WIDGETS_ADDWIDGCONT');
38 JText::script('VBO_WIDGETS_RESTDEFAULT');
39 JText::script('VBO_WIDGETS_ADDNEWWIDG');
40 JText::script('VBO_WIDGETS_SAVINGMAP');
41 JText::script('VBO_WIDGETS_ERRSAVINGMAP');
42 JText::script('VBO_WIDGETS_LASTUPD');
43 JText::script('VBO_WIDGETS_ENTERSECTNAME');
44 JText::script('VBO_WIDGETS_NEWSECT');
45 JText::script('VBO_WIDGETS_CONFRMELEM');
46 JText::script('VBO_WIDGETS_SELCONTSIZE');
47 JText::script('VBO_WIDGETS_UPDWIDGCONT');
48 JText::script('VBO_WIDGETS_EDITWIDGCONT');
49 JText::script('VBO_WIDGETS_ERRDISPWIDG');
50 JText::script('VBO_STICKYN_TITLE');
51 JText::script('VBO_STICKYN_TEXT');
52 JText::script('VBO_STICKYN_TEXT2');
53 JText::script('VBO_STICKYN_CUSTOMURI');
54 JText::script('VBO_BROWSER_NOTIFS_ON');
55 JText::script('VBO_BROWSER_NOTIFS_OFF');
56 JText::script('VBO_BROWSER_NOTIFS_OFF_HELP');
57 JText::script('VBO_ADMIN_WIDGET');
58 JText::script('VBO_CONGRATS');
59
60 /**
61 * Monitor request vars to see if a widget should be loaded within a modal.
62 * Only the dashboard at the moment allows to render an admin widget within
63 * a modal through query string values, because all other pages will render
64 * the multitask panel that can quickly render any admin widget.
65 *
66 * @since 1.16.0 (J) - 1.6.0 (WP)
67 */
68 $app = JFactory::getApplication();
69
70 $load_widget = $app->input->get('load_widget', '');
71 $injected_data = $app->input->get('multitask_data', [], 'array');
72 if (!empty($load_widget) && $desired_widget = $widgets_helper->getWidget($load_widget)) {
73 $injected_data['_modalTitle'] = $desired_widget->getName();
74 $payload_json = json_encode($injected_data);
75
76 // append script to DOM to render the widget within a modal
77 JFactory::getDocument()->addScriptDeclaration(
78 <<<JS
79 (function($) {
80 'use strict';
81
82 $(function() {
83 setTimeout(() => {
84 VBOCore.renderModalWidget('$load_widget', $payload_json, false);
85 }, 500);
86 });
87 })(jQuery);
88 JS
89 );
90 }
91
92 ?>
93 <div class="vbo-admin-widgets-wrap">
94 <?php
95 if ($vbo_auth_global) {
96 ?>
97 <div class="vbo-admin-widgets-commands">
98 <div class="vbo-admin-widgets-commands-info" data-vbomanagewidgets="1" style="display: none;">
99 <div class="vbo-admin-widgets-commands-info-inner">
100 <span class="vbo-admin-widgets-commands-info-txt"><?php echo JText::translate('VBO_WIDGETS_AUTOSAVE'); ?></span>
101 <div class="vbo-admin-widgets-commands-info-restore">
102 <a href="index.php?option=com_vikbooking&task=reset_admin_widgets" class="btn btn-secondary" onclick="return vboWidgetsRestoreMap();"><?php echo JText::translate('VBO_WIDGETS_RESTDEFAULTSHORT'); ?></a>
103 </div>
104 <div class="vbo-admin-widgets-suggest-notifications-cont" style="display: none;">
105 <span class="vbo-suggest-notifications-wrap">
106 <button class="vbo-dash-suggest-notifications-btn vbo-suggest-notifications-btn" type="button"><?php VikBookingIcons::e('bell', 'can-shake') ?></button>
107 </span>
108 </div>
109 </div>
110 </div>
111 <div class="vbo-admin-widgets-commands-mng">
112 <span class="vbo-admin-widgets-commands-mng-toggle"><?php echo $vbo_app->printYesNoButtons('vbocustwidgets', JText::translate('VBYES'), JText::translate('VBNO'), 0, 1, 0, 'vboWidgetsToggleManage(false);'); ?></span>
113 <span class="vbo-admin-widgets-commands-mng-lbl" onclick="vboWidgetsToggleManage(true);"><?php VikBookingIcons::e('cogs'); ?> <?php echo JText::translate('VBO_WIDGETS_CUSTWIDGETS'); ?></span>
114 </div>
115 </div>
116 <?php
117 }
118 ?>
119 <div class="vbo-admin-widgets-list">
120 <?php
121 foreach ($widgets_map->sections as $seck => $section) {
122 ?>
123 <div class="vbo-admin-widgets-section">
124 <div class="vbo-admin-widgets-section-name" data-vbomanagewidgets="1" style="display: none;">
125 <span class="vbo-admin-widgets-elem-cmds-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>
126 <span class="vbo-admin-widgets-section-name-val"><?php echo $section->name; ?></span>
127 <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-section-cmds">
128 <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditSection(this);"><?php VikBookingIcons::e('edit'); ?></span>
129 <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveSection(this);"><?php VikBookingIcons::e('trash'); ?></span>
130 </div>
131 </div>
132 <?php
133 if (!isset($section->containers)) {
134 $section->containers = array();
135 }
136 $tot_containers = count($section->containers);
137 foreach ($section->containers as $conk => $container) {
138 $container_css = $widgets_helper->getContainerCssClass($container->size);
139 ?>
140 <div class="vbo-admin-widgets-container <?php echo $container_css; ?>" data-vbowidgetcontsize="<?php echo $container->size; ?>" data-totcontainers="<?php echo $tot_containers; ?>">
141 <div class="vbo-admin-widgets-container-name" data-vbomanagewidgets="1" style="display: none;">
142 <span class="vbo-admin-widgets-container-name-val"><?php echo $widgets_helper->getContainerName($container->size); ?></span>
143 <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-container-cmds">
144 <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditContainer(this);"><?php VikBookingIcons::e('edit'); ?></span>
145 <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveContainer(this);"><?php VikBookingIcons::e('trash'); ?></span>
146 </div>
147 </div>
148 <?php
149 if (!isset($container->widgets)) {
150 $container->widgets = array();
151 }
152 foreach ($container->widgets as $widk => $widget_id) {
153 $widget_instance = $widgets_helper->getWidget($widget_id);
154 if ($widget_instance === false) {
155 continue;
156 }
157 ?>
158 <div class="vbo-admin-widgets-widget" data-vbowidgetid="<?php echo $widget_instance->getIdentifier(); ?>">
159 <div class="vbo-admin-widgets-widget-info" data-vbomanagewidgets="1" style="display: none;">
160 <div class="vbo-admin-widgets-widget-info-inner">
161 <div class="vbo-admin-widgets-widget-details">
162 <span class="vbo-admin-widgets-widget-info-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>
163 <h4 class="vbo-admin-widgets-widget-info-name">
164 <span><?php echo $widget_instance->getName(); ?></span>
165 <span class="vbo-admin-widgets-widget-remove" onclick="vboWidgetsRemoveWidget(this);"><?php VikBookingIcons::e('trash'); ?></span>
166 </h4>
167 </div>
168 <div class="vbo-admin-widgets-widget-info-descr"><?php echo $widget_instance->getDescription(); ?></div>
169 </div>
170 </div>
171 <div class="vbo-admin-widgets-widget-output">
172 <?php $widget_instance->render(); ?>
173 </div>
174 </div>
175 <?php
176 }
177 ?>
178 <div class="vbo-admin-widgets-widget vbo-admin-widgets-widget-addnew" data-vbomanagewidgets="1" style="display: none;">
179 <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddWidget(this);">
180 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
181 </div>
182 </div>
183 </div>
184 <?php
185 }
186 ?>
187 <div class="vbo-admin-widgets-container vbo-admin-widgets-container-addnew" data-vbomanagewidgets="1" style="display: none;">
188 <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddContainer(this);">
189 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
190 </div>
191 </div>
192 </div>
193 <?php
194 }
195 ?>
196 <div class="vbo-admin-widgets-section vbo-admin-widgets-section-addnew" data-vbomanagewidgets="1" style="display: none;">
197 <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddSection();">
198 <span><?php VikBookingIcons::e('plus-circle'); ?></span>
199 </div>
200 </div>
201 </div>
202 </div>
203
204 <div class="vbo-modal-overlay-block vbo-modal-overlay-block-dashwidgets">
205 <a class="vbo-modal-overlay-close" href="javascript: void(0);"></a>
206 <div class="vbo-modal-overlay-content vbo-modal-overlay-content-dashwidgets">
207 <div class="vbo-modal-overlay-content-head vbo-modal-overlay-content-head-dashwidgets">
208 <h3><span id="vbo-modal-widgets-title"></span> <span class="vbo-modal-overlay-close-times" onclick="hideVboModalWidgets();">&times;</span></h3>
209 </div>
210 <div class="vbo-modal-overlay-content-body vbo-modal-overlay-content-body-scroll">
211 <div class="vbo-modal-widgets-newcontainer vbo-modal-widgets-forms" style="display: none;">
212 <div class="vbo-modal-widgets-form-data-fields">
213 <div class="vbo-modal-widgets-form-data-field">
214 <label for="vbo-newcontainer-size"><?php echo JText::translate('VBO_WIDGETS_CONTSIZE'); ?></label>
215 <select id="vbo-newcontainer-size">
216 <?php
217 foreach ($widgets_helper->getContainerClassNames() as $class_key => $class_name_data) {
218 ?>
219 <option value="<?php echo $class_key; ?>" data-cssclass="<?php echo $class_name_data['css']; ?>"><?php echo $class_name_data['name']; ?></option>
220 <?php
221 }
222 ?>
223 </select>
224 <input type="hidden" id="vbo-newcontainer-upd" value="0" />
225 </div>
226 </div>
227 </div>
228 <div class="vbo-modal-widgets-newwidget vbo-modal-widgets-forms" style="display: none;">
229 <div class="vbo-modal-widgets-form-data-fields">
230 <div class="vbo-modal-widgets-form-data-field">
231 <label><?php echo JText::translate('VBO_WIDGETS_SELWIDGADD'); ?></label>
232 </div>
233 <div class="vbo-modal-widgets-form-data-field vbo-modal-widgets-list">
234 <input type="hidden" id="vbo-newwidget-id" value="" />
235 <?php
236 foreach ($widgets_names as $widget_data) {
237 ?>
238 <div class="vbo-modal-widget-wrap vbo-admin-widget-style-<?php echo $widget_data->style; ?>" data-vbowidgetid="<?php echo $widget_data->id; ?>" onclick="vboWidgetsSelectWidget('<?php echo $widget_data->id; ?>');">
239 <div class="vbo-modal-widget-cont-top">
240 <div class="vbo-modal-widget-icon">
241 <span><?php echo $widget_data->icon; ?></span>
242 </div>
243 <div class="vbo-modal-widget-add">
244 <span onclick="vboWidgetsAddWidgetToDoc('<?php echo $widget_data->id; ?>');"><?php VikBookingIcons::e('plus-circle'); ?></span>
245 </div>
246 </div>
247 <div class="vbo-modal-widget-cont-main">
248 <div class="vbo-modal-widget-name">
249 <span><?php echo $widget_data->name; ?></span>
250 </div>
251 <div class="vbo-modal-widget-descr">
252 <span><?php echo $widget_data->descr; ?></span>
253 </div>
254 </div>
255 </div>
256 <?php
257 }
258 ?>
259 </div>
260 <div class="vbo-modal-widgets-form-data-field vbo-newwidget-descr" style="display: none;"></div>
261 </div>
262 </div>
263 <?php
264 if ($widgets_welcome) {
265 ?>
266 <div class="vbo-widgets-welcome-wrap vbo-modal-widgets-forms" style="display: none;">
267 <div class="vbo-widgets-welcome-inner">
268 <p><?php echo JText::translate('VBO_WIDGETS_WELCOME_DESC1'); ?></p>
269 <p><?php echo JText::translate('VBO_WIDGETS_WELCOME_DESC2'); ?></p>
270 <div class="vbo-widgets-welcome-demo">
271 <div class="vbo-widgets-welcome-demo-section">
272 <span class="vbo-widgets-welcome-demo-section-lbl"><?php echo JText::translate('VBO_WIDGETS_NEWSECT'); ?></span>
273 <div class="vbo-widgets-welcome-demo-container">
274 <span class="vbo-widgets-welcome-demo-container-lbl"><?php echo JText::translate('VBO_WIDGETS_ADDWIDGCONT'); ?></span>
275 <div class="vbo-widgets-welcome-demo-widget">
276 <span class="vbo-widgets-welcome-demo-widget-lbl"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDNEWWIDG'); ?></span>
277 </div>
278 </div>
279 <div class="vbo-widgets-welcome-demo-container">
280 <span class="vbo-widgets-welcome-demo-container-lbl"><?php echo JText::translate('VBO_WIDGETS_ADDWIDGCONT'); ?></span>
281 <div class="vbo-widgets-welcome-demo-widget">
282 <span class="vbo-widgets-welcome-demo-widget-lbl"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDNEWWIDG'); ?></span>
283 </div>
284 </div>
285 </div>
286 </div>
287 </div>
288 </div>
289 <?php
290 }
291 ?>
292 </div>
293 <div class="vbo-modal-overlay-content-footer">
294 <div class="vbo-modal-footer-newcontainer vbo-modal-widgets-forms-footer" style="display: none;">
295 <div class="vbo-modal-overlay-content-footer-right">
296 <button type="button" class="btn btn-success" id="vbo-newcontainer-btn" onclick="vboWidgetsAddContainerToDoc();"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDWIDGCONT'); ?></button>
297 </div>
298 </div>
299 <div class="vbo-modal-footer-newwidget vbo-modal-widgets-forms-footer" style="display: none;">
300 <div class="vbo-modal-overlay-content-footer-right">
301 <button type="button" class="btn btn-success" onclick="vboWidgetsAddWidgetToDoc();"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBO_WIDGETS_ADDNEWWIDG'); ?></button>
302 </div>
303 </div>
304 <div class="vbo-modal-footer-welcome vbo-modal-widgets-forms-footer" style="display: none;">
305 <div class="vbo-modal-overlay-content-footer-left">
306 <button type="button" class="btn btn-secondary" onclick="vboWidgetsCloseWelcome(1);"><?php echo JText::translate('VBOBTNDONTREMIND'); ?></button>
307 </div>
308 <div class="vbo-modal-overlay-content-footer-right">
309 <button type="button" class="btn btn-success" onclick="vboWidgetsCloseWelcome(0);"><?php echo JText::translate('VBOBTNKEEPREMIND'); ?></button>
310 </div>
311 </div>
312 </div>
313 </div>
314 </div>
315
316 <script type="text/javascript">
317 /**
318 * Declare global scope variables.
319 */
320 var vbo_admin_widgets_map = <?php echo json_encode($widgets_map); ?>;
321 var vbo_admin_widgets_names = <?php echo json_encode($widgets_names); ?>;
322
323 var vbo_admin_widgets_last_section = null,
324 vbo_admin_widgets_last_container = null,
325 vbo_admin_widgets_initpos_section = 0,
326 vbo_admin_widgets_initpos_container = 0,
327 vbo_admin_widgets_initpos_widget = 0,
328 vbo_admin_widgets_initinst_widget = -1,
329 vbo_admin_widgets_allow_drop = false,
330 vbo_admin_widgets_sugg_notifs = false;
331
332 var vbo_modal_widgets_on = false;
333
334 var vbo_admin_widgets_welcome = <?php echo $widgets_welcome ? 'true' : 'false'; ?>;
335
336 /**
337 * Shows the modal window
338 */
339 function vboOpenModalWidgets() {
340 jQuery('.vbo-modal-overlay-block-dashwidgets').show();
341 vbo_modal_widgets_on = true;
342 }
343
344 /**
345 * Hides the modal window
346 */
347 function hideVboModalWidgets() {
348 if (vbo_modal_widgets_on === true) {
349 jQuery(".vbo-modal-overlay-block-dashwidgets").fadeOut(400, function() {
350 jQuery(".vbo-modal-overlay-content-dashwidgets").show();
351 jQuery(".vbo-modal-widgets-forms").hide();
352 jQuery(".vbo-modal-widgets-forms-footer").hide();
353 });
354 // turn flag off
355 vbo_modal_widgets_on = false;
356 }
357 }
358
359 /**
360 * Toggles the widget customizer mode
361 */
362 function vboWidgetsToggleManage(trigger) {
363 if (trigger === true) {
364 jQuery('input[name="vbocustwidgets"]').trigger('click');
365 return;
366 }
367 if (!jQuery('input[name="vbocustwidgets"]').is(':checked')) {
368 jQuery('div[data-vbomanagewidgets="1"]').hide();
369 jQuery('.vbo-admin-widgets-widget-output').show();
370 jQuery('.vbo-admin-widgets-list').removeClass('vbo-admin-widgets-list-customize');
371 } else {
372 jQuery('.vbo-admin-widgets-widget-output').hide();
373 jQuery('div[data-vbomanagewidgets="1"]').show();
374 jQuery('.vbo-admin-widgets-list').addClass('vbo-admin-widgets-list-customize');
375 // show welcome (if necessary)
376 vboWidgetsShowWelcome();
377 // handle notification suggestions
378 if (!vbo_admin_widgets_sugg_notifs && VBOCore.notificationsEnabled() === false) {
379 vbo_admin_widgets_sugg_notifs = true;
380 jQuery('.vbo-admin-widgets-suggest-notifications-cont').show();
381 VBOCore.suggestNotifications('.vbo-dash-suggest-notifications-btn');
382 }
383 }
384 }
385
386 /**
387 * Opens the modal window with the welcome message for the admin widgets customizer.
388 */
389 function vboWidgetsShowWelcome() {
390 if (!vbo_admin_widgets_welcome || !jQuery('.vbo-widgets-welcome-wrap').length) {
391 return;
392 }
393 // prevent this from being displayed again in the same page flow
394 vbo_admin_widgets_welcome = false;
395 // display welcome container
396 jQuery('.vbo-widgets-welcome-wrap').show();
397 jQuery('.vbo-modal-footer-welcome').show();
398 // set modal title
399 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_WELCOME'));
400 // display modal
401 vboOpenModalWidgets();
402 // declare timeouts to add the animate class to the welcome elements
403 setTimeout(() => {
404 // animate container
405 jQuery('.vbo-widgets-welcome-demo-section').addClass('vbo-widgets-welcome-animate');
406 }, 1000);
407 setTimeout(() => {
408 // animate first section
409 jQuery('.vbo-widgets-welcome-demo-container').first().addClass('vbo-widgets-welcome-animate');
410 }, 2000);
411 setTimeout(() => {
412 // animate last section
413 jQuery('.vbo-widgets-welcome-demo-container').last().addClass('vbo-widgets-welcome-animate');
414 }, 3000);
415 setTimeout(() => {
416 // animate widgets
417 jQuery('.vbo-widgets-welcome-demo-widget').addClass('vbo-widgets-welcome-animate');
418 }, 4000);
419 }
420
421 /**
422 * Closes the modal window for the welcome text by storing an action.
423 */
424 function vboWidgetsCloseWelcome(hidenext) {
425 // dismiss modal
426 hideVboModalWidgets();
427 // AJAX request to update the welcome status
428 VBOCore.doAjax(
429 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=admin_widgets_welcome'); ?>",
430 {
431 hide_welcome: hidenext,
432 tmpl: "component"
433 },
434 (response) => {
435 try {
436 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
437 if (!obj_res.hasOwnProperty('status')) {
438 // request failed
439 console.error('Could not update welcome status', obj_res);
440 }
441 } catch(err) {
442 console.error('could not parse JSON response when updating the welcome status', err, response);
443 }
444 },
445 (error) => {
446 console.error(error);
447 }
448 );
449 }
450
451 /**
452 * This will fire during the throttle of the save-map event.
453 * Saves the updated admin widgets map onto the database.
454 */
455 function vboHandleMapSaving() {
456 // update info status to "saving..."
457 jQuery('.vbo-admin-widgets-commands-info-txt').removeClass('vbo-admin-widgets-error').html('<?php VikBookingIcons::e('refresh', 'fa-spin fa-fw'); ?> ' + Joomla.JText._('VBO_WIDGETS_SAVINGMAP'));
458
459 // prepare AJAX request data
460 var saving_request = {
461 tmpl: "component"
462 }
463 Object.assign(saving_request, vbo_admin_widgets_map);
464
465 // make the request
466 VBOCore.doAjax(
467 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=save_admin_widgets'); ?>",
468 saving_request,
469 (response) => {
470 try {
471 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
472 if (!obj_res.status) {
473 // request failed
474 console.error('Could not update the map', obj_res);
475 // update info status to "error..."
476 jQuery('.vbo-admin-widgets-commands-info-txt').addClass('vbo-admin-widgets-error').text(Joomla.JText._('VBO_WIDGETS_ERRSAVINGMAP'));
477 } else {
478 // set last updated time
479 var now = new Date;
480 var hours = now.getHours();
481 hours = hours < 10 ? '0' + hours : hours;
482 var minutes = now.getMinutes();
483 minutes = minutes < 10 ? '0' + minutes : minutes;
484 var seconds = now.getSeconds();
485 seconds = seconds < 10 ? '0' + seconds : seconds;
486 var full_time_now = hours + ':' + minutes + ':' + seconds;
487 // update info status to "last update time"
488 jQuery('.vbo-admin-widgets-commands-info-txt').removeClass('vbo-admin-widgets-error').html('<?php VikBookingIcons::e('check-circle'); ?> ' + Joomla.JText._('VBO_WIDGETS_LASTUPD') + ': ' + full_time_now);
489 }
490 } catch(err) {
491 console.error('could not parse JSON response when updating the map', err, response);
492 // update info status to "error..."
493 jQuery('.vbo-admin-widgets-commands-info-txt').addClass('vbo-admin-widgets-error').text(Joomla.JText._('VBO_WIDGETS_ERRSAVINGMAP'));
494 }
495 },
496 (error) => {
497 console.error(error.responseText);
498 // update info status to "error..."
499 jQuery('.vbo-admin-widgets-commands-info-txt').addClass('vbo-admin-widgets-error').text(Joomla.JText._('VBO_WIDGETS_ERRSAVINGMAP'));
500 }
501 );
502 }
503
504 /**
505 * Makes all sections sortable. Do not use .disableSelection() or this
506 * will break all [contenteditable] elements and their focus/selection events.
507 */
508 function vboMakeSectionsSortable() {
509 jQuery('.vbo-admin-widgets-list').sortable({
510 axix: 'x',
511 cursor: 'move',
512 handle: '.vbo-admin-widgets-section-name .vbo-admin-widgets-elem-cmds-drag',
513 items: '.vbo-admin-widgets-section:not(.vbo-admin-widgets-section-addnew)',
514 revert: false,
515 start: function(event, ui) {
516 // update global initial position for section
517 vbo_admin_widgets_initpos_section = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(ui.item));
518 },
519 update: function(event, ui) {
520 var new_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(ui.item));
521 // update global map object - move originial section to new position
522 vbo_admin_widgets_map.sections.splice(new_sect_index, 0, vbo_admin_widgets_map.sections.splice(vbo_admin_widgets_initpos_section, 1)[0]);
523
524 // trigger the save-map event
525 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
526 }
527 });
528 }
529
530 /**
531 * Makes all widgets sortable. Do not use .disableSelection() or this
532 * will break all [contenteditable] elements and their focus/selection events.
533 */
534 function vboMakeWidgetsSortable() {
535 jQuery('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').sortable({
536 connectWith: '.vbo-admin-widgets-container:not(.vbo-admin-widgets-container-addnew)',
537 cursor: 'move',
538 dropOnEmpty: true,
539 handle: '.vbo-admin-widgets-widget-details .vbo-admin-widgets-widget-info-drag',
540 helper: 'clone',
541 items: '.vbo-admin-widgets-widget:not(.vbo-admin-widgets-widget-addnew)',
542 placeholder: 'vbo-admin-widgets-container-tmpdrop',
543 revert: false,
544 start: function(event, ui) {
545 // allow drop
546 vbo_admin_widgets_allow_drop = true;
547 // calculate initial positions
548 var initial_widget = jQuery(ui.item);
549 var initial_section = initial_widget.closest('.vbo-admin-widgets-section');
550 var initial_container = initial_widget.closest('.vbo-admin-widgets-container');
551 // update global initial position for section
552 vbo_admin_widgets_initpos_section = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(initial_section);
553 // update global initial position for container
554 vbo_admin_widgets_initpos_container = initial_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(initial_container);
555 // update global initial position for widget
556 vbo_admin_widgets_initpos_widget = initial_container.find('.vbo-admin-widgets-widget').not('.vbo-admin-widgets-widget-addnew').index(initial_widget);
557 // update global initial instance index for this type of widget
558 var widget_type = initial_widget.attr('data-vbowidgetid');
559 vbo_admin_widgets_initinst_widget = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + widget_type + '"]').index(initial_widget);
560 },
561 update: function(event, ui) {
562 var dropped_widget = jQuery(ui.item);
563 var dropped_section = dropped_widget.closest('.vbo-admin-widgets-section');
564 var dropped_container = dropped_widget.closest('.vbo-admin-widgets-container');
565 // calculate new element positions
566 var new_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(dropped_section);
567 var new_cont_index = dropped_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(dropped_container);
568 var new_widg_index = dropped_container.find('.vbo-admin-widgets-widget').not('.vbo-admin-widgets-widget-addnew').index(dropped_widget);
569
570 if (new_sect_index != vbo_admin_widgets_initpos_section || new_cont_index != vbo_admin_widgets_initpos_container) {
571 /**
572 * Widget has been moved to a connected list, to a different section or container.
573 * Multiple "update" events will be fired, one for each target, so 2 in total.
574 */
575 if (vbo_admin_widgets_allow_drop !== true) {
576 // both events contain the same dropped target information (ui), so we skip any later event
577 return;
578 }
579
580 // disable drop for any sub-sequent event
581 vbo_admin_widgets_allow_drop = false;
582
583 // update global map object - remove original widget
584 vbo_admin_widgets_map.sections[vbo_admin_widgets_initpos_section]['containers'][vbo_admin_widgets_initpos_container]['widgets'].splice(vbo_admin_widgets_initpos_widget, 1);
585
586 // update global map object - push new widget
587 vbo_admin_widgets_map.sections[new_sect_index]['containers'][new_cont_index]['widgets'].splice(new_widg_index, 0, dropped_widget.attr('data-vbowidgetid'));
588 } else {
589 /**
590 * Widget has been sorted from the same section and container list.
591 * Only one "update" event will be fired.
592 */
593
594 // update global map object - move original widget to new position
595 vbo_admin_widgets_map.sections[vbo_admin_widgets_initpos_section]['containers'][vbo_admin_widgets_initpos_container]['widgets'].splice(
596 new_widg_index,
597 0,
598 vbo_admin_widgets_map.sections[vbo_admin_widgets_initpos_section]['containers'][vbo_admin_widgets_initpos_container]['widgets'].splice(vbo_admin_widgets_initpos_widget, 1)[0]
599 );
600 }
601
602 // calculate new instance index for this type of widget
603 var widget_type = dropped_widget.attr('data-vbowidgetid');
604 var new_instance_index = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + widget_type + '"]').index(dropped_widget);
605 if (vbo_admin_widgets_initinst_widget >= 0 && new_instance_index >= 0 && vbo_admin_widgets_initinst_widget != new_instance_index) {
606 // widget instance index has changed, and since we have multiple instances of this widget, we may need to update its settings
607
608 // the widget method to call
609 var call_method = 'sortInstance';
610 // make a silent call for the widget in case it needs to perform actions when removing an instance
611 VBOCore.doAjax(
612 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
613 {
614 widget_id: widget_type,
615 widget_index_old: vbo_admin_widgets_initinst_widget,
616 widget_index_new: new_instance_index,
617 call: call_method,
618 tmpl: "component"
619 },
620 (response) => {
621 try {
622 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
623 if (!obj_res.hasOwnProperty(call_method)) {
624 console.error('Unexpected JSON response', obj_res);
625 }
626 } catch(err) {
627 console.error('could not parse JSON response', err, response);
628 }
629 },
630 (error) => {
631 console.error(error.responseText);
632 }
633 );
634 }
635
636 // trigger the save-map event
637 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
638
639 }
640 });
641 }
642
643 /**
644 * Declares document ready event processes.
645 */
646 jQuery(function() {
647
648 /**
649 * Dismiss modal window with Esc.
650 */
651 jQuery(document).keydown(function(e) {
652 if (e.keyCode == 27) {
653 if (vbo_modal_widgets_on === true) {
654 hideVboModalWidgets();
655 }
656 }
657 });
658
659 /**
660 * Dismiss modal window by clicking on an external element.
661 */
662 jQuery(document).mouseup(function(e) {
663 if (!vbo_modal_widgets_on) {
664 return false;
665 }
666 if (vbo_modal_widgets_on) {
667 var vbo_overlay_cont = jQuery(".vbo-modal-overlay-content-dashwidgets");
668 if (!vbo_overlay_cont.is(e.target) && vbo_overlay_cont.has(e.target).length === 0) {
669 hideVboModalWidgets();
670 }
671 }
672 });
673
674 /**
675 * Make all current sections and widgets sortable.
676 */
677 vboMakeSectionsSortable();
678 vboMakeWidgetsSortable();
679
680 /**
681 * Add event listener to the save-map event with debounce handler.
682 */
683 document.addEventListener('vbo-admin-widgets-savemap', VBOCore.debounceEvent(vboHandleMapSaving, 2000));
684
685 /**
686 * Setup browser notifications and admin widgets core features.
687 */
688 VBOCore.setOptions({
689 is_vbo: true,
690 widget_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
691 assets_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=widgets_get_assets'); ?>",
692 multitask_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_multitask_widgets'); ?>",
693 watchdata_ajax_uri: "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=widgets_watch_data'); ?>",
694 current_page: "dashboard",
695 current_page_uri: "<?php echo htmlspecialchars((string) JUri::getInstance(), ENT_QUOTES); ?>",
696 panel_opts: {
697 notif_on_class: "vbo-sidepanel-notifications-on",
698 notif_off_class: "vbo-sidepanel-notifications-off",
699 },
700 notif_audio_url: "<?php echo $notif_audio_url; ?>",
701 tn_texts: {
702 notifs_enabled: Joomla.JText._('VBO_BROWSER_NOTIFS_ON'),
703 notifs_disabled: Joomla.JText._('VBO_BROWSER_NOTIFS_OFF'),
704 notifs_disabled_help: Joomla.JText._('VBO_BROWSER_NOTIFS_OFF_HELP'),
705 admin_widget: Joomla.JText._('VBO_ADMIN_WIDGET'),
706 congrats: Joomla.JText._('VBO_CONGRATS'),
707 },
708 default_loading_body: '<?php VikBookingIcons::e('circle-notch', 'fa-spin fa-fw'); ?>',
709 }).setupNotifications();
710
711 });
712
713 /**
714 * Asks for confirmation to restore the default widgets map
715 */
716 function vboWidgetsRestoreMap() {
717 if (confirm(Joomla.JText._('VBO_WIDGETS_RESTDEFAULT'))) {
718 return true;
719 } else {
720 return false;
721 }
722 }
723
724 /**
725 * Adds a new section to the document
726 */
727 function vboWidgetsAddSection() {
728 var tot_sections = jQuery('.vbo-admin-widgets-section').length;
729 var sect_name_new = prompt(Joomla.JText._('VBO_WIDGETS_ENTERSECTNAME'), Joomla.JText._('VBO_WIDGETS_NEWSECT') + ' #' + (tot_sections + 1));
730 if (sect_name_new != null && sect_name_new != '') {
731 var html_section_new = '<div class="vbo-admin-widgets-section" id="vbo-admin-widgets-section-' + (tot_sections + 1) + '">';
732 html_section_new += ' <div class="vbo-admin-widgets-section-name" data-vbomanagewidgets="1">';
733 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
734 html_section_new += ' <span class="vbo-admin-widgets-section-name-val">' + sect_name_new + '</span>';
735 html_section_new += ' <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-section-cmds">';
736 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditSection(this);"><?php VikBookingIcons::e('edit'); ?></span>';
737 html_section_new += ' <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveSection(this);"><?php VikBookingIcons::e('trash'); ?></span>';
738 html_section_new += ' </div>';
739 html_section_new += ' </div>';
740 html_section_new += ' <div class="vbo-admin-widgets-container vbo-admin-widgets-container-addnew" data-vbomanagewidgets="1">';
741 html_section_new += ' <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddContainer(this);">';
742 html_section_new += ' <span><?php VikBookingIcons::e('plus-circle'); ?></span>';
743 html_section_new += ' </div>';
744 html_section_new += ' </div>';
745 html_section_new += '</div>';
746 jQuery('.vbo-admin-widgets-section-addnew').before(html_section_new);
747
748 // update global map object
749 vbo_admin_widgets_map.sections.push({
750 name: sect_name_new,
751 containers: []
752 });
753
754 // trigger the save-map event
755 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
756 }
757 }
758
759 /**
760 * Prompts the new section name to update it
761 */
762 function vboWidgetsEditSection(elem) {
763 var cur_sect_name_elm = jQuery(elem).closest('.vbo-admin-widgets-section-name').find('.vbo-admin-widgets-section-name-val');
764 if (!cur_sect_name_elm || !cur_sect_name_elm.length) {
765 console.error('Could not find section to edit');
766 return false;
767 }
768 var cur_sect_name_val = cur_sect_name_elm.text();
769 // find current index of selected section in the map
770 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
771 var sect_name_new = prompt(Joomla.JText._('VBO_WIDGETS_ENTERSECTNAME'), cur_sect_name_val);
772 if (sect_name_new != null && sect_name_new != '') {
773 cur_sect_name_elm.text(sect_name_new);
774 // update global map object
775 vbo_admin_widgets_map.sections[cur_sect_index]['name'] = sect_name_new;
776 // trigger the save-map event
777 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
778 }
779 }
780
781 /**
782 * Asks for confirmation before removing the selected section
783 */
784 function vboWidgetsRemoveSection(elem) {
785 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
786 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
787 // remove section from document
788 jQuery(elem).closest('.vbo-admin-widgets-section').remove();
789 // update global map object
790 vbo_admin_widgets_map.sections.splice(cur_sect_index, 1);
791 // trigger the save-map event
792 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
793 }
794 }
795
796 /**
797 * Displays the modal window to create a new widgets container
798 */
799 function vboWidgetsAddContainer(elem) {
800 // update last section selected
801 vbo_admin_widgets_last_section = jQuery(elem).closest('.vbo-admin-widgets-section');
802 if (!vbo_admin_widgets_last_section || !vbo_admin_widgets_last_section.length) {
803 // parent section not found
804 console.error('parent section not found for adding a container');
805 return false;
806 }
807 // turn update flag off
808 jQuery('#vbo-newcontainer-upd').val(0);
809 // display new container form
810 jQuery('.vbo-modal-widgets-newcontainer').show();
811 jQuery('.vbo-modal-footer-newcontainer').show();
812 // set new container form button
813 jQuery('#vbo-newcontainer-btn').html('<?php VikBookingIcons::e('plus-circle'); ?> ' + Joomla.JText._('VBO_WIDGETS_ADDWIDGCONT'));
814 // set modal title
815 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_ADDWIDGCONT'));
816 // display modal
817 vboOpenModalWidgets();
818 }
819
820 /**
821 * Adds or updates one widgets container in the document.
822 */
823 function vboWidgetsAddContainerToDoc() {
824 var mode = jQuery('#vbo-newcontainer-upd').val() > 0 ? 'update' : 'new';
825 if (mode == 'new' && (!vbo_admin_widgets_last_section || !vbo_admin_widgets_last_section.length)) {
826 // parent section not found
827 console.error('parent section not found for adding a container');
828 return false;
829 }
830 if (mode == 'update' && (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length)) {
831 // current container not found
832 console.error('current container not found');
833 return false;
834 }
835
836 // get new container size and CSS class
837 var cont_size = jQuery('#vbo-newcontainer-size').val();
838 var cont_css = jQuery('#vbo-newcontainer-size').find('option:selected').attr('data-cssclass');
839 var cont_name = jQuery('#vbo-newcontainer-size').find('option:selected').text();
840 if (!cont_size || !cont_size.length || !cont_css.length) {
841 console.error('new container size missing');
842 alert(Joomla.JText._('VBO_WIDGETS_SELCONTSIZE'));
843 return false;
844 }
845
846 if (mode == 'update') {
847 // update container class, size and title
848 vbo_admin_widgets_last_container.removeClass().addClass('vbo-admin-widgets-container ' + cont_css).attr('data-vbowidgetcontsize', cont_size).find('.vbo-admin-widgets-container-name-val').text(cont_name);
849
850 // update global map object
851 var cur_cont_index = vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(vbo_admin_widgets_last_container);
852 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section'));
853 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['size'] = cont_size;
854
855 // trigger the save-map event
856 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
857 } else {
858 // update containers count for a better styling
859 var all_sect_conts = vbo_admin_widgets_last_section.find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew');
860 var new_sect_conts = all_sect_conts.length + 1;
861 all_sect_conts.attr('data-totcontainers', new_sect_conts);
862
863 // build new container
864 var html_container_new = '<div class="vbo-admin-widgets-container ' + cont_css + '" data-vbowidgetcontsize="' + cont_size + '" data-totcontainers="' + new_sect_conts + '">';
865 html_container_new += ' <div class="vbo-admin-widgets-container-name" data-vbomanagewidgets="1">';
866 html_container_new += ' <span class="vbo-admin-widgets-container-name-val">' + cont_name + '</span>';
867 html_container_new += ' <div class="vbo-admin-widget-elem-cmds vbo-admin-widgets-container-cmds">';
868 html_container_new += ' <span class="vbo-admin-widgets-elem-cmds-edit" onclick="vboWidgetsEditContainer(this);"><?php VikBookingIcons::e('edit'); ?></span>';
869 html_container_new += ' <span class="vbo-admin-widgets-elem-cmds-remove" onclick="vboWidgetsRemoveContainer(this);"><?php VikBookingIcons::e('trash'); ?></span>';
870 html_container_new += ' </div>';
871 html_container_new += ' </div>';
872 html_container_new += ' <div class="vbo-admin-widgets-widget vbo-admin-widgets-widget-addnew" data-vbomanagewidgets="1">';
873 html_container_new += ' <div class="vbo-admin-widgets-plus-box" onclick="vboWidgetsAddWidget(this);">';
874 html_container_new += ' <span><?php VikBookingIcons::e('plus-circle'); ?></span>';
875 html_container_new += ' </div>';
876 html_container_new += ' </div>';
877 html_container_new += '</div>';
878
879 // append new container HTML
880 vbo_admin_widgets_last_section.find('.vbo-admin-widgets-container-addnew').before(html_container_new);
881
882 // update global map object
883 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_section);
884 vbo_admin_widgets_map.sections[cur_sect_index]['containers'].push({
885 size: cont_size,
886 widgets: []
887 });
888
889 // trigger the save-map event
890 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
891 }
892
893 // close modal window
894 hideVboModalWidgets();
895
896 // unset last section and container
897 vbo_admin_widgets_last_section = null;
898 vbo_admin_widgets_last_container = null;
899 }
900
901 /**
902 * Displays the modal window for editing the selected container
903 */
904 function vboWidgetsEditContainer(elem) {
905 // update last container selected
906 vbo_admin_widgets_last_container = jQuery(elem).closest('.vbo-admin-widgets-container');
907 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
908 // parent container not found
909 console.error('parent container not found');
910 return false;
911 }
912 // turn update flag on
913 jQuery('#vbo-newcontainer-upd').val(1);
914 // set current container size
915 jQuery('#vbo-newcontainer-size').val(vbo_admin_widgets_last_container.attr('data-vbowidgetcontsize')).trigger('change');
916 // display edit container form
917 jQuery('.vbo-modal-widgets-newcontainer').show();
918 jQuery('.vbo-modal-footer-newcontainer').show();
919 // set edit container form button
920 jQuery('#vbo-newcontainer-btn').html('<?php VikBookingIcons::e('check'); ?> ' + Joomla.JText._('VBO_WIDGETS_UPDWIDGCONT'));
921 // set modal title
922 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_EDITWIDGCONT'));
923 // display modal
924 vboOpenModalWidgets();
925 }
926
927 /**
928 * Asks for confirmation before removing the selected container
929 */
930 function vboWidgetsRemoveContainer(elem) {
931 var all_sect_conts = jQuery(elem).closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew');
932 var new_sect_conts = (all_sect_conts.length - 1);
933 var cur_cont_index = all_sect_conts.index(jQuery(elem).closest('.vbo-admin-widgets-container'));
934 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(jQuery(elem).closest('.vbo-admin-widgets-section'));
935 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
936 // update containers count for a better styling
937 all_sect_conts.attr('data-totcontainers', new_sect_conts);
938 // remove container from document
939 jQuery(elem).closest('.vbo-admin-widgets-container').remove();
940 // update global map object
941 vbo_admin_widgets_map.sections[cur_sect_index]['containers'].splice(cur_cont_index, 1);
942 // trigger the save-map event
943 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
944 }
945 }
946
947 /**
948 * Displays the modal window to create a new widget
949 */
950 function vboWidgetsAddWidget(elem) {
951 // update last container selected
952 vbo_admin_widgets_last_container = jQuery(elem).closest('.vbo-admin-widgets-container');
953 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
954 // parent container not found
955 console.error('parent container not found for adding a widget');
956 return false;
957 }
958 // display new widget form
959 jQuery('.vbo-modal-widgets-newwidget').show();
960 jQuery('.vbo-modal-footer-newwidget').show();
961 // unset any previously selected widget
962 jQuery('#vbo-newwidget-id').val('');
963 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected vbo-modal-widget-notselected');
964 // set modal title
965 jQuery('#vbo-modal-widgets-title').text(Joomla.JText._('VBO_WIDGETS_ADDNEWWIDG'));
966 // display modal
967 vboOpenModalWidgets();
968 }
969
970 /**
971 * Updates the description in the modal window for the selected widget
972 */
973 function vboWidgetSetNewDescr(widget_id) {
974 // always empty the description box
975 jQuery('.vbo-newwidget-descr').html('');
976 if (!widget_id.length) {
977 return '';
978 }
979 // seek for this widget id
980 for (var i in vbo_admin_widgets_names) {
981 if (!vbo_admin_widgets_names.hasOwnProperty(i)) {
982 continue;
983 }
984 if (vbo_admin_widgets_names[i]['id'] == widget_id) {
985 jQuery('.vbo-newwidget-descr').html(vbo_admin_widgets_names[i]['descr']);
986 return vbo_admin_widgets_names[i]['descr'];
987 }
988 }
989 return '';
990 }
991
992 /**
993 * Makes the current widget selected, ready to be added to the document
994 */
995 function vboWidgetsSelectWidget(widget_id) {
996 if (!widget_id) {
997 return false;
998 }
999
1000 // remove selected class from all widgets, add un-selected class
1001 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected').not('[data-vbowidgetid="' + widget_id + '"]').addClass('vbo-modal-widget-notselected');
1002 // add selected class to the current widget
1003 jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + widget_id + '"]').addClass('vbo-modal-widget-selected').removeClass('vbo-modal-widget-notselected');
1004 // populate hidden field value
1005 jQuery('#vbo-newwidget-id').val(widget_id);
1006
1007 return true;
1008 }
1009
1010 /**
1011 * Adds the new selected widget to the document
1012 */
1013 function vboWidgetsAddWidgetToDoc(force_widget_id) {
1014 if (!vbo_admin_widgets_last_container || !vbo_admin_widgets_last_container.length) {
1015 // parent container not found
1016 console.error('parent container not found for adding a container');
1017 return false;
1018 }
1019
1020 // get new widget id, name and descr
1021 var widget_id = null,
1022 widget_name = null,
1023 widget_descr = null;
1024 if (force_widget_id) {
1025 // plus button clicked on widget
1026 jQuery('#vbo-newwidget-id').val(force_widget_id);
1027 // remove selected class from all widgets, add un-selected class
1028 jQuery('.vbo-modal-widget-wrap').removeClass('vbo-modal-widget-selected').not('[data-vbowidgetid="' + force_widget_id + '"]').addClass('vbo-modal-widget-notselected');
1029 // add selected class to the current widget
1030 jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + force_widget_id + '"]').addClass('vbo-modal-widget-selected').removeClass('vbo-modal-widget-notselected');
1031 widget_id = force_widget_id;
1032 } else {
1033 // selected widget was clicked to be added
1034 widget_id = jQuery('#vbo-newwidget-id').val();
1035 }
1036 widget_name = jQuery('.vbo-modal-widget-wrap[data-vbowidgetid="' + widget_id + '"]').find('.vbo-modal-widget-name').text();
1037 if (!widget_id || !widget_id.length || !widget_name || !widget_name.length) {
1038 console.error('new widget id missing');
1039 return false;
1040 }
1041 // get and update the description for the currently selected widget
1042 widget_descr = vboWidgetSetNewDescr(widget_id);
1043
1044 // build new widget
1045 var html_widget_new = '<div class="vbo-admin-widgets-widget" data-vbowidgetid="' + widget_id + '">';
1046 html_widget_new += ' <div class="vbo-admin-widgets-widget-info" data-vbomanagewidgets="1">';
1047 html_widget_new += ' <div class="vbo-admin-widgets-widget-info-inner">';
1048 html_widget_new += ' <div class="vbo-admin-widgets-widget-details">';
1049 html_widget_new += ' <span class="vbo-admin-widgets-widget-info-drag"><?php VikBookingIcons::e('ellipsis-v'); ?></span>';
1050 html_widget_new += ' <h4 class="vbo-admin-widgets-widget-info-name">';
1051 html_widget_new += ' <span>' + widget_name + '</span>';
1052 html_widget_new += ' <span class="vbo-admin-widgets-widget-remove" onclick="vboWidgetsRemoveWidget(this);"><?php VikBookingIcons::e('trash'); ?></span>';
1053 html_widget_new += ' </h4>';
1054 html_widget_new += ' </div>';
1055 html_widget_new += ' <div class="vbo-admin-widgets-widget-info-descr">' + widget_descr + '</div>';
1056 html_widget_new += ' </div>';
1057 html_widget_new += ' </div>';
1058 html_widget_new += ' <div class="vbo-admin-widgets-widget-output" style="display: none;"></div>';
1059 html_widget_new += '</div>';
1060
1061 // wrap the new HTML into a collection object
1062 var elem_widget_new = jQuery(html_widget_new);
1063
1064 // append new widget HTML
1065 vbo_admin_widgets_last_container.find('.vbo-admin-widgets-widget-addnew').before(elem_widget_new);
1066
1067 // update global map object
1068 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section'));
1069 var cur_cont_index = vbo_admin_widgets_last_container.closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(vbo_admin_widgets_last_container);
1070 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['widgets'].push(widget_id);
1071
1072 // trigger the save-map event
1073 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1074
1075 // close modal window
1076 hideVboModalWidgets();
1077
1078 // unset last container
1079 vbo_admin_widgets_last_container = null;
1080
1081 // populate widget output via AJAX
1082 vboWidgetsLoadWidgetContent(elem_widget_new, widget_id);
1083 }
1084
1085 /**
1086 * Asks for confirmation before removing the selected widget
1087 */
1088 function vboWidgetsRemoveWidget(elem) {
1089 var vbo_widget_elem = jQuery(elem).closest('.vbo-admin-widgets-widget');
1090 var cur_widg_id = vbo_widget_elem.attr('data-vbowidgetid');
1091 var cur_sect_index = jQuery('.vbo-admin-widgets-section').not('.vbo-admin-widgets-section-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-section'));
1092 var cur_cont_index = vbo_widget_elem.closest('.vbo-admin-widgets-section').find('.vbo-admin-widgets-container').not('.vbo-admin-widgets-container-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-container'));
1093 var cur_widg_index = vbo_widget_elem.closest('.vbo-admin-widgets-container').find('.vbo-admin-widgets-widget').not('.vbo-admin-widgets-widget-addnew').index(vbo_widget_elem.closest('.vbo-admin-widgets-widget'));
1094 if (confirm(Joomla.JText._('VBO_WIDGETS_CONFRMELEM'))) {
1095 // calculate widget instance index for its type
1096 var widget_instance_index = jQuery('.vbo-admin-widgets-widget[data-vbowidgetid="' + cur_widg_id + '"]').index(vbo_widget_elem);
1097
1098 // the widget method to call
1099 var call_method = 'removeInstance';
1100 // make a silent call for the widget in case it needs to perform actions when removing an instance
1101 VBOCore.doAjax(
1102 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
1103 {
1104 widget_id: cur_widg_id,
1105 widget_instance: widget_instance_index,
1106 call: call_method,
1107 tmpl: "component"
1108 },
1109 (response) => {
1110 try {
1111 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1112 if (!obj_res.hasOwnProperty(call_method)) {
1113 console.error('Unexpected JSON response', obj_res);
1114 }
1115 } catch(err) {
1116 console.error('could not parse JSON response', err, response);
1117 }
1118 },
1119 (error) => {
1120 console.error(error.responseText);
1121 }
1122 );
1123
1124 // remove widget from document
1125 vbo_widget_elem.remove();
1126 // update global map object
1127 vbo_admin_widgets_map.sections[cur_sect_index]['containers'][cur_cont_index]['widgets'].splice(cur_widg_index, 1);
1128 // trigger the save-map event
1129 document.dispatchEvent(new Event('vbo-admin-widgets-savemap'));
1130 }
1131 }
1132
1133 /**
1134 * Populates the content of the newly added widget.
1135 */
1136 function vboWidgetsLoadWidgetContent(container, widget_id) {
1137 if (!container || !container.find('.vbo-admin-widgets-widget-output').length) {
1138 console.error('Could not find new widget container');
1139 return false;
1140 }
1141
1142 // the widget method to call
1143 var call_method = 'render';
1144
1145 VBOCore.doAjax(
1146 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=exec_admin_widget'); ?>",
1147 {
1148 widget_id: widget_id,
1149 call: call_method,
1150 tmpl: "component"
1151 },
1152 (response) => {
1153 try {
1154 var obj_res = typeof response === 'string' ? JSON.parse(response) : response;
1155 if (obj_res.hasOwnProperty(call_method)) {
1156 // populate new widget content
1157 container.find('.vbo-admin-widgets-widget-output').html(obj_res[call_method]);
1158 } else {
1159 console.error('Unexpected JSON response', obj_res);
1160 }
1161 } catch(err) {
1162 console.error('could not parse JSON response', err, response);
1163 }
1164 },
1165 (error) => {
1166 console.error(error.responseText);
1167 alert(Joomla.JText._('VBO_WIDGETS_ERRDISPWIDG'));
1168 }
1169 );
1170 }
1171 </script>
1172