A modern, lightweight JavaScript year picker component designed for Django input fields. Features a clean dropdown interface with decade navigation, customizable year ranges, and full modal support.
- Clean UI: Modern dropdown interface with decade-based navigation (12 years per view)
- Modal Compatible: Intelligent z-index handling and positioning for modals
- Customizable Ranges: Set minimum and maximum year constraints
- Responsive Design: Mobile-friendly with adaptive layouts
- Django Integration: Designed specifically for Django forms and input fields
- Event System: Custom events for form integration and validation
- Accessibility: Keyboard navigation and screen reader support
- Auto-positioning: Smart dropdown positioning that adjusts to viewport boundaries
- Zero Dependencies: Pure vanilla JavaScript implementation
year_picker/
├── src/
│ ├── year_picker.js # Source JavaScript
│ └── year_picker.css # Source CSS
├── dist/
│ ├── year_picker.min.js # Minified JavaScript
│ ├── year_picker.min.js.map
│ └── year_picker.min.css # Minified CSS
├── examples/
│ ├── basic.html # Basic usage example
│ └── django-example.html # Django integration
├── package.json
├── README.md
├── LICENSE
└── .gitignore
-
Download the files from the
dist/directory -
Copy to your Django static files directory:
static/ ├── css/ │ └── year_picker.min.css └── js/ └── year_picker.min.js -
Include in your template:
{% load static %} <link rel="stylesheet" href="{% static 'css/year_picker.min.css' %}"> <script src="{% static 'js/year_picker.min.js' %}"></script>
Use the source files from src/ for development:
{% load static %}
<link rel="stylesheet" href="{% static 'css/year_picker.css' %}">
<script src="{% static 'js/year_picker.js' %}"></script>npm install django-year_pickerAdd the year_picker-input class to any input field:
<input type="text" id="year-field" class="year_picker-input"
data-min-year="1950" data-max-year="2030" placeholder="Select year">The year picker will automatically initialize when the page loads.
# forms.py
from django import forms
class MyForm(forms.Form):
birth_year = forms.CharField(
max_length=4,
widget=forms.TextInput(attrs={
'class': 'form-control year_picker-input',
'data-min-year': '1900',
'data-max-year': '2023',
'placeholder': 'Select birth year'
})
)Configure individual fields using HTML data attributes:
data-min-year: Minimum selectable year (default: 1900)data-max-year: Maximum selectable year (default: 2100)
<input type="text" class="year_picker-input"
data-min-year="2000"
data-max-year="2050">Initialize year picker for elements with a specific class:
// Initialize for elements with class 'my-year-field'
initYearPicker('my-year-field', {
minYear: 1980,
maxYear: 2030,
defaultYear: 2023
});Add year picker to elements matching a CSS selector:
// Add to all inputs with class 'year-input'
addYearPicker('.year-input', {
minYear: 2000,
maxYear: 2050
});Initialize with manual z-index override for modals:
initYearPickerForModal('modal-year-field', {
minYear: 1990,
maxYear: 2030,
zIndex: 10000
});Set z-index for existing year picker:
setYearPickerZIndex(99999);setYearPickerValue('my-field', 2023);const year = getYearPickerValue('my-field');clearYearPicker('my-field');const hasValue = hasYearPickerValue('my-field');Update field configuration:
updateYearPicker('my-field', {
minYear: 2020,
maxYear: 2030,
value: 2025
});Remove year picker from a field:
removeYearPicker('my-field');The year picker dispatches custom events for integration:
Triggered when a year is selected:
document.getElementById('my-field').addEventListener('yearSelected', function(e) {
console.log('Selected year:', e.detail.year);
console.log('Input element:', e.detail.input);
console.log('Programmatic:', e.detail.programmatic); // true if set via API
});Triggered when the field is cleared:
document.getElementById('my-field').addEventListener('yearCleared', function(e) {
console.log('Cleared year:', e.detail.oldValue);
console.log('Input element:', e.detail.input);
});Standard change event is also triggered for form compatibility:
document.getElementById('my-field').addEventListener('change', function(e) {
console.log('Field changed:', e.target.value);
});The component uses these CSS classes for styling:
.year_picker-input: Applied to input fields.year_picker-dropdown: Main dropdown container.year_picker-has-value: Added when field has a value.year-item.selected: Currently selected year.year-item.selectable: Selectable years.year-item.disabled: Disabled years (outside min/max range)
/* Custom input styling */
.year_picker-input {
border: 2px solid #e9ecef;
border-radius: 8px;
padding: 12px;
font-size: 16px;
}
.year_picker-input:focus {
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}
/* Custom dropdown styling */
.year_picker-dropdown {
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15);
}
/* Custom year item styling */
.year-item.selected {
background: #28a745;
border-color: #1e7e34;
}<!-- template.html -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="{% static 'css/year_picker.css' %}">
</head>
<body>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
<script src="{% static 'js/year_picker.js' %}"></script>
</body>
</html><!-- Modal with year picker -->
<div class="modal fade" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<input type="text" id="modal-year" class="form-control year_picker-input"
data-min-year="2000" data-max-year="2030">
</div>
</div>
</div>
</div>
<script>
// Initialize for modal with higher z-index
$('#myModal').on('shown.bs.modal', function() {
initYearPickerForModal('modal-year', {
zIndex: 10000
});
});
</script>- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- Internet Explorer 11 (with polyfills)
- No external JavaScript dependencies
- Pure vanilla JavaScript implementation
- CSS uses modern features (Grid, Flexbox)
This project is open source. Feel free to use and modify according to your needs.
When contributing:
- Maintain backward compatibility
- Test with different modal libraries (Bootstrap, Material-UI, etc.)
- Ensure responsive design works on all screen sizes
- Follow existing code style and patterns
- Update this README for any new features
- Initial release
- Basic year picker functionality
- Modal support with automatic z-index detection
- Responsive design
- Django form integration
- Custom event system
- Comprehensive JavaScript API