PageSourceSearch

https://auberge-boenlesgrab.fr/wp-content/plugins/aji-manager/asse…cf-special-slots-validation.js?ver=2.205.35

js auberge-boenlesgrab.fr collected 2026-09-30 11:31:20 UTC 7,436 bytes, 185 lines download raw bytes

1(function ($) {
2    'use strict';
3
4    /**
5     * Validate special takeaway pickup slots
6     * Ensures end_datetime is on the same day and after start_datetime
7     */
8    function initSpecialSlotsValidation() {
9        // Look for repeater rows containing both start_datetime and end_datetime
10        const validateDatetimeFields = function () {
11            $('.acf-repeater').each(function () {
12                const $repeater = $(this);
13                const $rows = $repeater.find('.acf-row:not(.acf-clone)');
14
15                $rows.each(function () {
16                    const $row = $(this);
17                    const $startField = $row.find('[data-name="start_datetime"]');
18                    const $endField = $row.find('[data-name="end_datetime"]');
19
20                    if ($startField.length && $endField.length) {
21                        // Find the actual input elements
22                        const $startInput = $startField.find('input[type="datetime-local"], input[type="text"]').first();
23                        const $endInput = $endField.find('input[type="datetime-local"], input[type="text"]').first();
24
25                        if ($startInput.length && $endInput.length) {
26                            // Add validation on blur
27                            $startInput.off('blur').on('blur', function () {
28                                validateEndDateTime($row, $startInput, $endInput, $endField);
29                            });
30
31                            $endInput.off('blur').on('blur', function () {
32                                validateEndDateTime($row, $startInput, $endInput, $endField);
33                            });
34
35                            // Add change event for real-time validation
36                            $startInput.off('change').on('change', function () {
37                                validateEndDateTime($row, $startInput, $endInput, $endField);
38                            });
39
40                            $endInput.off('change').on('change', function () {
41                                validateEndDateTime($row, $startInput, $endInput, $endField);
42                            });
43                        }
44                    }
45                });
46            });
47        };
48
49        const validateEndDateTime = function ($row, $startInput, $endInput, $endFieldWrapper) {
50            const startValue = $startInput.val();
51            const endValue = $endInput.val();
52
53            // Skip if either field is empty
54            if (!startValue || !endValue) {
55                clearValidationError($row, $endFieldWrapper);
56                return;
57            }
58
59            try {
60                // Parse datetime values
61                // ACF date_time_picker can return various formats (datetime-local or formatted string)
62                const startDate = parseDateTime(startValue);
63                const endDate = parseDateTime(endValue);
64
65                if (!startDate || !endDate) {
66                    clearValidationError($row, $endFieldWrapper);
67                    return;
68                }
69
70                // Check if dates are on the same day
71                const startDay = startDate.toDateString();
72                const endDay = endDate.toDateString();
73
74                if (startDay !== endDay) {
75                    showValidationError(
76                        $row,
77                        $endFieldWrapper,
78                        ajiAcfSpecialSlotsText?.same_day_error ||
79                        'La date de fin doit être le même jour que la date de début'
80                    );
81                    return;
82                }
83
84                // Check if end time is after start time
85                if (endDate <= startDate) {
86                    showValidationError(
87                        $row,
88                        $endFieldWrapper,
89                        ajiAcfSpecialSlotsText?.end_after_start_error ||
90                        'L\'heure de fin doit être après l\'heure de début'
91                    );
92                    return;
93                }
94
95                // All validations passed
96                clearValidationError($row, $endFieldWrapper);
97            } catch (error) {
98                console.warn('Error validating special slots datetime:', error);
99                clearValidationError($row, $endFieldWrapper);
100            }
101        };
102
103        const parseDateTime = function (value) {
104            if (!value) return null;
105
106            // Try parsing as ISO datetime format (datetime-local input type)
107            let date = new Date(value);
108            if (!isNaN(date.getTime())) {
109                return date;
110            }
111
112            // Try parsing common datetime formats
113            // Format: d/m/Y H:i (e.g., "15/11/2025 14:30")
114            const formats = [
115                { regex: /^(\d{2})\/(\d{2})\/(\d{4})\s(\d{2}):(\d{2})$/, groups: { day: 1, month: 2, year: 3, hour: 4, min: 5 } },
116                // Format: Y-m-d H:i (e.g., "2025-11-15 14:30")
117                { regex: /^(\d{4})-(\d{2})-(\d{2})\s(\d{2}):(\d{2})$/, groups: { year: 1, month: 2, day: 3, hour: 4, min: 5 } }
118            ];
119
120            for (let format of formats) {
121                const match = value.match(format.regex);
122                if (match) {
123                    const d = match[format.groups.day];
124                    const m = match[format.groups.month];
125                    const y = match[format.groups.year];
126                    const h = match[format.groups.hour];
127                    const min = match[format.groups.min];
128
129                    date = new Date(parseInt(y), parseInt(m) - 1, parseInt(d), parseInt(h), parseInt(min));
130                    if (!isNaN(date.getTime())) {
131                        return date;
132                    }
133                }
134            }
135
136            return null;
137        };
138
139        const showValidationError = function ($row, $endFieldWrapper, message) {
140            // Remove existing error if any
141            $endFieldWrapper.find('.aji-slot-validation-error').remove();
142
143            // Add error message inside end_datetime field
144            const $error = $(`<div class="aji-slot-validation-error" style="color: #e74c3c; font-size: 12px; margin-top: 5px; font-weight: bold; display: flex; align-items: center; gap: 6px;">
145                ${message}
146            </div>`);
147
148            $endFieldWrapper.append($error);
149            $row.addClass('aji-slot-has-error');
150        };
151
152        const clearValidationError = function ($row, $endFieldWrapper) {
153            $endFieldWrapper.find('.aji-slot-validation-error').remove();
154            $row.removeClass('aji-slot-has-error');
155        };
156
157        // Initial validation on page load
158        validateDatetimeFields();
159
160        // Re-validate when new rows are added to repeater
161        $(document).on('acf/insert_row', function () {
162            setTimeout(validateDatetimeFields, 100);
163        });
164
165        // Also watch for changes via ACF field update
166        if (window.acf) {
167            acf.addAction('render_field', function () {
168                validateDatetimeFields();
169            });
170        }
171    }
172
173    // Initialize when document is ready
174    $(document).ready(function () {
175        initSpecialSlotsValidation();
176    });
177
178    // Also initialize after ACF loads (for AJAX contexts)
179    if (window.acf) {
180        acf.addAction('ready', function () {
181            initSpecialSlotsValidation();
182        });
183    }
184
185})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.