PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.6.2
LatePoint – Calendar Booking Plugin for Appointments and Events v5.6.2
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 / _delete-confirm.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 3 weeks 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 3 weeks ago updates.js 3 months ago
_delete-confirm.js
126 lines
1 /*
2 * Copyright (c) 2024 LatePoint LLC. All rights reserved.
3 */
4
5 /*
6 * The single "type delete to confirm" modal for the whole plugin. One modal, one set of
7 * os-delete-confirm-* classes, used for both:
8 *
9 * 1. Single-record delete — add the class os-delete-confirm to a normal data-os-action button that
10 * has data-os-prompt (services now, any tab later). Optional data-os-confirm-title sets the modal
11 * heading; the data-os-prompt text is the body. The gate in bin/actions.js calls
12 * latepoint_delete_confirm_show($trigger); on confirm the button's own data-os-action flow runs.
13 *
14 * 2. Bulk delete (e.g. appointments) — call it programmatically with an options object:
15 * latepoint_delete_confirm_show({ title: '...', body: '...', onConfirm: function(){ ... } });
16 * and run the bulk request inside onConfirm.
17 *
18 * Shared strings (prompt template, confirm word, buttons) come from the single
19 * latepoint_delete_confirm_i18n localized object.
20 */
21
22 function latepoint_delete_confirm_show(arg){
23 var i18n = (typeof latepoint_delete_confirm_i18n !== 'undefined') ? latepoint_delete_confirm_i18n : {};
24 var confirm_word = i18n.modal_confirm_word || 'delete';
25 var title, body, onConfirm;
26
27 if(arg && arg.jquery){
28 // Single delete: a .os-delete-confirm data-os-action button. Heading comes from the optional
29 // data-os-confirm-title; the body is the button's existing data-os-prompt message. On confirm,
30 // re-fire its click with os-delete-approved set so the gate in bin/actions.js skips the modal and runs
31 // its normal data-os-action flow.
32 var $trigger = arg;
33 title = $trigger.data('os-confirm-title') || '';
34 body = $trigger.data('os-prompt') || '';
35 onConfirm = function(){ $trigger.data('os-delete-approved', true).trigger('click'); };
36 } else {
37 // Programmatic caller (e.g. appointments bulk delete): supplies its own title/body + confirm callback.
38 arg = arg || {};
39 title = arg.title || '';
40 body = arg.body || '';
41 onConfirm = (typeof arg.onConfirm === 'function') ? arg.onConfirm : function(){};
42 }
43
44 // Build the modal via jQuery DOM methods so every user/translator supplied string is assigned via
45 // .text()/.attr() (jQuery escapes it) — no risk of attribute break-out or HTML injection.
46 var $modal = jQuery('<div class="os-delete-confirm-modal" />').attr('data-confirm-word', confirm_word);
47 $modal.append('<div class="os-delete-confirm-icon"><i class="latepoint-icon latepoint-icon-trash-2"></i></div>');
48 if(title) $modal.append(jQuery('<h3 class="os-delete-confirm-title" />').text(title));
49 if(body) $modal.append(jQuery('<p class="os-delete-confirm-body" />').text(body));
50
51 var promptParts = String(i18n.modal_confirm_prompt || '').split('%s');
52 var $prompt = jQuery('<p class="os-delete-confirm-prompt" />');
53 $prompt.append(document.createTextNode(promptParts[0] || ''));
54 $prompt.append(jQuery('<strong />').text(confirm_word));
55 $prompt.append(document.createTextNode(promptParts[1] || ''));
56 $modal.append($prompt);
57
58 $modal.append(
59 jQuery('<input type="text" class="os-delete-confirm-input" autocomplete="off" spellcheck="false" />')
60 .attr('placeholder', i18n.modal_input_placeholder || '')
61 );
62
63 var $actions = jQuery('<div class="os-delete-confirm-actions" />');
64 $actions.append(
65 jQuery('<a href="#" class="latepoint-btn latepoint-btn-grey latepoint-btn-outline os-delete-confirm-cancel" />')
66 .append(jQuery('<span />').text(i18n.modal_cancel || ''))
67 );
68 $actions.append(
69 jQuery('<a href="#" class="latepoint-btn latepoint-btn-danger os-delete-confirm-go is-disabled" />')
70 .attr('aria-disabled', 'true')
71 .append(jQuery('<span />').text(i18n.modal_confirm || ''))
72 );
73 $modal.append($actions);
74
75 latepoint_show_data_in_lightbox($modal[0].outerHTML, 'width-500 os-delete-confirm-lightbox', true);
76
77 // latepoint_show_data_in_lightbox appends the lightbox synchronously, so the modal is already in the
78 // DOM — store the confirm callback and focus the input without a fragile setTimeout.
79 var $live = jQuery('.os-delete-confirm-lightbox .os-delete-confirm-modal');
80 $live.data('onConfirm', onConfirm);
81 $live.find('.os-delete-confirm-input').trigger('focus');
82 }
83
84 function latepoint_delete_confirm_run($go){
85 var onConfirm = $go.closest('.os-delete-confirm-modal').data('onConfirm');
86 latepoint_lightbox_close();
87 if(typeof onConfirm === 'function') onConfirm();
88 }
89
90 function latepoint_init_delete_confirm(){
91 var $body = jQuery('body');
92 if($body.data('os-delete-confirm-bound')) return;
93 $body.data('os-delete-confirm-bound', true);
94
95 $body.on('input keyup paste', '.os-delete-confirm-input', function(){
96 var $modal = jQuery(this).closest('.os-delete-confirm-modal');
97 var required = String($modal.data('confirm-word') || 'delete').toLowerCase();
98 var typed = String(jQuery(this).val() || '').trim().toLowerCase();
99 var $go = $modal.find('.os-delete-confirm-go');
100 if(typed === required){
101 $go.removeClass('is-disabled').attr('aria-disabled', 'false');
102 } else {
103 $go.addClass('is-disabled').attr('aria-disabled', 'true');
104 }
105 });
106
107 $body.on('keydown', '.os-delete-confirm-input', function(e){
108 if(e.which !== 13) return;
109 e.preventDefault();
110 var $go = jQuery(this).closest('.os-delete-confirm-modal').find('.os-delete-confirm-go');
111 if(!$go.hasClass('is-disabled')) $go.trigger('click');
112 });
113
114 $body.on('click', '.os-delete-confirm-cancel', function(e){
115 e.preventDefault();
116 latepoint_lightbox_close();
117 });
118
119 $body.on('click', '.os-delete-confirm-go', function(e){
120 e.preventDefault();
121 var $this = jQuery(this);
122 if($this.hasClass('is-disabled') || $this.hasClass('os-loading')) return;
123 latepoint_delete_confirm_run($this);
124 });
125 }
126