jQuery plugin for date and time selection combining both date picker and time picker functionality with extensive customization and internationalization support
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive event system with callbacks for user interactions and picker state changes.
Events that fire during picker initialization, display, and destruction.
interface LifecycleEvents {
/** Called when picker is shown */
onShow?: (currentTime: Date, input: HTMLInputElement) => boolean | void;
/** Called when picker is closed */
onClose?: (currentTime: Date, input: HTMLInputElement) => boolean | void;
/** Called when picker HTML is generated */
onGenerate?: (currentTime: Date, input: HTMLInputElement) => void;
}Usage Examples:
// Track picker visibility
$('#tracked-picker').datetimepicker({
onShow: function(currentTime, input) {
console.log('Picker opened for:', input.id);
$(input).addClass('picker-active');
// Return false to prevent showing
if ($(input).hasClass('disabled')) {
return false;
}
},
onClose: function(currentTime, input) {
console.log('Picker closed for:', input.id);
$(input).removeClass('picker-active');
// Return false to prevent closing
if (!currentTime) {
alert('Please select a date');
return false;
}
},
onGenerate: function(currentTime, input) {
console.log('Picker HTML generated');
// Customize generated HTML here
}
});Events that fire when users select dates, times, or navigate the picker.
interface SelectionEvents {
/** Called when a date is selected */
onSelectDate?: (currentTime: Date, input: HTMLInputElement) => void;
/** Called when a time is selected */
onSelectTime?: (currentTime: Date, input: HTMLInputElement) => void;
/** Called when month changes */
onChangeMonth?: (currentTime: Date, input: HTMLInputElement) => void;
/** Called when year changes */
onChangeYear?: (currentTime: Date, input: HTMLInputElement) => void;
/** Called when any datetime value changes */
onChangeDateTime?: (currentTime: Date, input: HTMLInputElement) => void;
}Usage Examples:
// React to date/time selections
$('#event-picker').datetimepicker({
onSelectDate: function(currentTime, input) {
console.log('Date selected:', currentTime.toDateString());
// Update other UI elements
$('#selected-date').text(currentTime.toDateString());
// Enable time picker or other form elements
$('#time-section').show();
},
onSelectTime: function(currentTime, input) {
console.log('Time selected:', currentTime.toTimeString());
// Validate business hours
var hour = currentTime.getHours();
if (hour < 9 || hour > 17) {
alert('Please select a time during business hours (9 AM - 5 PM)');
}
},
onChangeDateTime: function(currentTime, input) {
console.log('DateTime changed:', currentTime);
// Update hidden field for form submission
$('#hidden-datetime').val(currentTime.toISOString());
// Trigger validation
$(input).trigger('validate');
},
onChangeMonth: function(currentTime, input) {
console.log('Month changed to:', currentTime.getMonth() + 1);
// Update available dates for the new month
updateAvailableDates(currentTime.getFullYear(), currentTime.getMonth());
},
onChangeYear: function(currentTime, input) {
console.log('Year changed to:', currentTime.getFullYear());
// Update holidays or special dates for the new year
updateHolidays(currentTime.getFullYear());
}
});Event for customizing week number display.
interface WeekNumberEvent {
/** Custom week number calculation */
onGetWeekOfYear?: (date: Date) => number;
}Usage Examples:
// Custom week number calculation
$('#week-picker').datetimepicker({
weeks: true,
onGetWeekOfYear: function(date) {
// Custom ISO week calculation
var target = new Date(date.valueOf());
var dayNr = (date.getDay() + 6) % 7;
target.setDate(target.getDate() - dayNr + 3);
var firstThursday = target.valueOf();
target.setMonth(0, 1);
if (target.getDay() !== 4) {
target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
}
return 1 + Math.ceil((firstThursday - target) / 604800000);
}
});
// Financial week calculation (starts on Monday)
$('#financial-week').datetimepicker({
weeks: true,
dayOfWeekStart: 1,
onGetWeekOfYear: function(date) {
// Financial year week calculation
var startOfYear = new Date(date.getFullYear(), 0, 1);
var days = Math.floor((date - startOfYear) / (24 * 60 * 60 * 1000));
return Math.ceil((days + startOfYear.getDay() + 1) / 7);
}
});Common patterns for using events effectively.
Usage Examples:
// Form validation integration
$('#validated-date').datetimepicker({
onChangeDateTime: function(currentTime, input) {
// Clear previous validation errors
$(input).removeClass('is-invalid');
$('#date-error').hide();
if (currentTime) {
// Validate against business rules
if (currentTime < new Date()) {
$(input).addClass('is-invalid');
$('#date-error').text('Date cannot be in the past').show();
}
}
},
onClose: function(currentTime, input) {
// Final validation on close
if (!currentTime) {
$(input).addClass('is-invalid');
$('#date-error').text('Date is required').show();
return false; // Prevent closing
}
}
});
// AJAX integration
$('#ajax-date').datetimepicker({
onSelectDate: function(currentTime, input) {
// Load available times for selected date
$.ajax({
url: '/api/available-times',
data: { date: currentTime.toISOString().split('T')[0] },
success: function(times) {
var picker = $(input).data('xdsoft_datetimepicker');
picker.setOptions({
allowTimes: times
});
}
});
}
});
// Multi-picker coordination
$('#start-date').datetimepicker({
onChangeDateTime: function(currentTime, input) {
if (currentTime) {
// Update end date minimum
var endPicker = $('#end-date').data('xdsoft_datetimepicker');
endPicker.setOptions({
minDate: currentTime
});
}
}
});
$('#end-date').datetimepicker({
onChangeDateTime: function(currentTime, input) {
if (currentTime) {
// Update start date maximum
var startPicker = $('#start-date').data('xdsoft_datetimepicker');
startPicker.setOptions({
maxDate: currentTime
});
}
}
});
// Analytics tracking
$('#analytics-date').datetimepicker({
onShow: function(currentTime, input) {
// Track picker usage
gtag('event', 'datepicker_opened', {
'event_category': 'form_interaction',
'element_id': input.id
});
},
onSelectDate: function(currentTime, input) {
// Track date selections
gtag('event', 'date_selected', {
'event_category': 'form_interaction',
'selected_date': currentTime.toISOString().split('T')[0]
});
}
});
// Custom styling based on events
$('#styled-picker').datetimepicker({
onShow: function(currentTime, input) {
$(input).closest('.form-group').addClass('picker-active');
},
onClose: function(currentTime, input) {
$(input).closest('.form-group').removeClass('picker-active');
if (currentTime) {
$(input).closest('.form-group').addClass('has-value');
} else {
$(input).closest('.form-group').removeClass('has-value');
}
},
onChangeMonth: function(currentTime, input) {
// Add month-specific styling
var picker = $(input).data('xdsoft_datetimepicker');
var month = currentTime.getMonth();
picker.addClass('month-' + month);
// Remove other month classes
for (var i = 0; i < 12; i++) {
if (i !== month) {
picker.removeClass('month-' + i);
}
}
}
});Handle errors and edge cases in event callbacks.
Usage Examples:
// Safe event handling
$('#safe-picker').datetimepicker({
onChangeDateTime: function(currentTime, input) {
try {
if (currentTime && typeof currentTime.getTime === 'function') {
// Safe date operations
var timestamp = currentTime.getTime();
if (!isNaN(timestamp)) {
// Process valid date
updateRelatedFields(currentTime);
}
}
} catch (e) {
console.error('Error in onChangeDateTime:', e);
}
},
onShow: function(currentTime, input) {
try {
// Safely access DOM elements
var $input = $(input);
if ($input.length) {
$input.trigger('picker:show');
}
} catch (e) {
console.error('Error in onShow:', e);
// Don't prevent showing on error
}
},
onClose: function(currentTime, input) {
try {
// Validate before allowing close
if ($(input).hasClass('required') && !currentTime) {
$(input).addClass('error');
return false; // Prevent closing
}
$(input).removeClass('error');
} catch (e) {
console.error('Error in onClose:', e);
// Allow closing on error to prevent picker getting stuck
}
}
});