0
# Event Handling
1
2
Comprehensive event system with callbacks for user interactions and picker state changes.
3
4
## Capabilities
5
6
### Lifecycle Events
7
8
Events that fire during picker initialization, display, and destruction.
9
10
```javascript { .api }
11
interface LifecycleEvents {
12
/** Called when picker is shown */
13
onShow?: (currentTime: Date, input: HTMLInputElement) => boolean | void;
14
/** Called when picker is closed */
15
onClose?: (currentTime: Date, input: HTMLInputElement) => boolean | void;
16
/** Called when picker HTML is generated */
17
onGenerate?: (currentTime: Date, input: HTMLInputElement) => void;
18
}
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
// Track picker visibility
25
$('#tracked-picker').datetimepicker({
26
onShow: function(currentTime, input) {
27
console.log('Picker opened for:', input.id);
28
$(input).addClass('picker-active');
29
30
// Return false to prevent showing
31
if ($(input).hasClass('disabled')) {
32
return false;
33
}
34
},
35
36
onClose: function(currentTime, input) {
37
console.log('Picker closed for:', input.id);
38
$(input).removeClass('picker-active');
39
40
// Return false to prevent closing
41
if (!currentTime) {
42
alert('Please select a date');
43
return false;
44
}
45
},
46
47
onGenerate: function(currentTime, input) {
48
console.log('Picker HTML generated');
49
// Customize generated HTML here
50
}
51
});
52
```
53
54
### Selection Events
55
56
Events that fire when users select dates, times, or navigate the picker.
57
58
```javascript { .api }
59
interface SelectionEvents {
60
/** Called when a date is selected */
61
onSelectDate?: (currentTime: Date, input: HTMLInputElement) => void;
62
/** Called when a time is selected */
63
onSelectTime?: (currentTime: Date, input: HTMLInputElement) => void;
64
/** Called when month changes */
65
onChangeMonth?: (currentTime: Date, input: HTMLInputElement) => void;
66
/** Called when year changes */
67
onChangeYear?: (currentTime: Date, input: HTMLInputElement) => void;
68
/** Called when any datetime value changes */
69
onChangeDateTime?: (currentTime: Date, input: HTMLInputElement) => void;
70
}
71
```
72
73
**Usage Examples:**
74
75
```javascript
76
// React to date/time selections
77
$('#event-picker').datetimepicker({
78
onSelectDate: function(currentTime, input) {
79
console.log('Date selected:', currentTime.toDateString());
80
81
// Update other UI elements
82
$('#selected-date').text(currentTime.toDateString());
83
84
// Enable time picker or other form elements
85
$('#time-section').show();
86
},
87
88
onSelectTime: function(currentTime, input) {
89
console.log('Time selected:', currentTime.toTimeString());
90
91
// Validate business hours
92
var hour = currentTime.getHours();
93
if (hour < 9 || hour > 17) {
94
alert('Please select a time during business hours (9 AM - 5 PM)');
95
}
96
},
97
98
onChangeDateTime: function(currentTime, input) {
99
console.log('DateTime changed:', currentTime);
100
101
// Update hidden field for form submission
102
$('#hidden-datetime').val(currentTime.toISOString());
103
104
// Trigger validation
105
$(input).trigger('validate');
106
},
107
108
onChangeMonth: function(currentTime, input) {
109
console.log('Month changed to:', currentTime.getMonth() + 1);
110
111
// Update available dates for the new month
112
updateAvailableDates(currentTime.getFullYear(), currentTime.getMonth());
113
},
114
115
onChangeYear: function(currentTime, input) {
116
console.log('Year changed to:', currentTime.getFullYear());
117
118
// Update holidays or special dates for the new year
119
updateHolidays(currentTime.getFullYear());
120
}
121
});
122
```
123
124
### Custom Week Number Calculation
125
126
Event for customizing week number display.
127
128
```javascript { .api }
129
interface WeekNumberEvent {
130
/** Custom week number calculation */
131
onGetWeekOfYear?: (date: Date) => number;
132
}
133
```
134
135
**Usage Examples:**
136
137
```javascript
138
// Custom week number calculation
139
$('#week-picker').datetimepicker({
140
weeks: true,
141
onGetWeekOfYear: function(date) {
142
// Custom ISO week calculation
143
var target = new Date(date.valueOf());
144
var dayNr = (date.getDay() + 6) % 7;
145
target.setDate(target.getDate() - dayNr + 3);
146
var firstThursday = target.valueOf();
147
target.setMonth(0, 1);
148
if (target.getDay() !== 4) {
149
target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
150
}
151
return 1 + Math.ceil((firstThursday - target) / 604800000);
152
}
153
});
154
155
// Financial week calculation (starts on Monday)
156
$('#financial-week').datetimepicker({
157
weeks: true,
158
dayOfWeekStart: 1,
159
onGetWeekOfYear: function(date) {
160
// Financial year week calculation
161
var startOfYear = new Date(date.getFullYear(), 0, 1);
162
var days = Math.floor((date - startOfYear) / (24 * 60 * 60 * 1000));
163
return Math.ceil((days + startOfYear.getDay() + 1) / 7);
164
}
165
});
166
```
167
168
### Event Handling Patterns
169
170
Common patterns for using events effectively.
171
172
**Usage Examples:**
173
174
```javascript
175
// Form validation integration
176
$('#validated-date').datetimepicker({
177
onChangeDateTime: function(currentTime, input) {
178
// Clear previous validation errors
179
$(input).removeClass('is-invalid');
180
$('#date-error').hide();
181
182
if (currentTime) {
183
// Validate against business rules
184
if (currentTime < new Date()) {
185
$(input).addClass('is-invalid');
186
$('#date-error').text('Date cannot be in the past').show();
187
}
188
}
189
},
190
191
onClose: function(currentTime, input) {
192
// Final validation on close
193
if (!currentTime) {
194
$(input).addClass('is-invalid');
195
$('#date-error').text('Date is required').show();
196
return false; // Prevent closing
197
}
198
}
199
});
200
201
// AJAX integration
202
$('#ajax-date').datetimepicker({
203
onSelectDate: function(currentTime, input) {
204
// Load available times for selected date
205
$.ajax({
206
url: '/api/available-times',
207
data: { date: currentTime.toISOString().split('T')[0] },
208
success: function(times) {
209
var picker = $(input).data('xdsoft_datetimepicker');
210
picker.setOptions({
211
allowTimes: times
212
});
213
}
214
});
215
}
216
});
217
218
// Multi-picker coordination
219
$('#start-date').datetimepicker({
220
onChangeDateTime: function(currentTime, input) {
221
if (currentTime) {
222
// Update end date minimum
223
var endPicker = $('#end-date').data('xdsoft_datetimepicker');
224
endPicker.setOptions({
225
minDate: currentTime
226
});
227
}
228
}
229
});
230
231
$('#end-date').datetimepicker({
232
onChangeDateTime: function(currentTime, input) {
233
if (currentTime) {
234
// Update start date maximum
235
var startPicker = $('#start-date').data('xdsoft_datetimepicker');
236
startPicker.setOptions({
237
maxDate: currentTime
238
});
239
}
240
}
241
});
242
243
// Analytics tracking
244
$('#analytics-date').datetimepicker({
245
onShow: function(currentTime, input) {
246
// Track picker usage
247
gtag('event', 'datepicker_opened', {
248
'event_category': 'form_interaction',
249
'element_id': input.id
250
});
251
},
252
253
onSelectDate: function(currentTime, input) {
254
// Track date selections
255
gtag('event', 'date_selected', {
256
'event_category': 'form_interaction',
257
'selected_date': currentTime.toISOString().split('T')[0]
258
});
259
}
260
});
261
262
// Custom styling based on events
263
$('#styled-picker').datetimepicker({
264
onShow: function(currentTime, input) {
265
$(input).closest('.form-group').addClass('picker-active');
266
},
267
268
onClose: function(currentTime, input) {
269
$(input).closest('.form-group').removeClass('picker-active');
270
271
if (currentTime) {
272
$(input).closest('.form-group').addClass('has-value');
273
} else {
274
$(input).closest('.form-group').removeClass('has-value');
275
}
276
},
277
278
onChangeMonth: function(currentTime, input) {
279
// Add month-specific styling
280
var picker = $(input).data('xdsoft_datetimepicker');
281
var month = currentTime.getMonth();
282
283
picker.addClass('month-' + month);
284
// Remove other month classes
285
for (var i = 0; i < 12; i++) {
286
if (i !== month) {
287
picker.removeClass('month-' + i);
288
}
289
}
290
}
291
});
292
```
293
294
### Error Handling in Events
295
296
Handle errors and edge cases in event callbacks.
297
298
**Usage Examples:**
299
300
```javascript
301
// Safe event handling
302
$('#safe-picker').datetimepicker({
303
onChangeDateTime: function(currentTime, input) {
304
try {
305
if (currentTime && typeof currentTime.getTime === 'function') {
306
// Safe date operations
307
var timestamp = currentTime.getTime();
308
if (!isNaN(timestamp)) {
309
// Process valid date
310
updateRelatedFields(currentTime);
311
}
312
}
313
} catch (e) {
314
console.error('Error in onChangeDateTime:', e);
315
}
316
},
317
318
onShow: function(currentTime, input) {
319
try {
320
// Safely access DOM elements
321
var $input = $(input);
322
if ($input.length) {
323
$input.trigger('picker:show');
324
}
325
} catch (e) {
326
console.error('Error in onShow:', e);
327
// Don't prevent showing on error
328
}
329
},
330
331
onClose: function(currentTime, input) {
332
try {
333
// Validate before allowing close
334
if ($(input).hasClass('required') && !currentTime) {
335
$(input).addClass('error');
336
return false; // Prevent closing
337
}
338
339
$(input).removeClass('error');
340
} catch (e) {
341
console.error('Error in onClose:', e);
342
// Allow closing on error to prevent picker getting stuck
343
}
344
}
345
});
346
```