Jalali-Calendar
- Active · last change 9-20-2026
- ★ 6 on GitHub
README
Jalali DatePicker for Delphi VCL
A professional Persian (Jalali) date picker component for Delphi VCL with full Data-Aware support and advanced UX.
Table of Contents
- Key Features
- Installation
- Quick Start
- Properties
- Events
- Keyboard Shortcuts
- Mouse Interaction
- Date Formats
- Icon Customization
- Data-Aware Usage
- Safety & Stability
- Requirements
- Preview
- Contributing
- License
- Author
✨ Key Features
- Full Jalali Calendar — Accurate Persian year, month, and day calculations
- Modern UI — Built-in sleek calendar icon with support for
TImageListandTPicture - Mouse-Driven UX — Click-to-select date parts (Year/Month/Day), Mouse Wheel scrolling
- Keyboard-Centric — Edit dates quickly without touching the mouse
- Data-Aware — Native
TDataSourcebinding withftDate/ftDateTimefield support - Multi-Monitor Aware — Smart dropdown positioning across multiple displays
- RTL Support — Full Right-to-Left alignment support
- Safe Hooking — Auto-close dropdown on outside clicks, form move, or resize via secure Windows API subclassing
- Smart Validation — Automatic input validation with a dedicated error event
🚀 Installation
Manual Install
- Clone the repository:
git clone https://github.com/YOUR_USERNAME/Jalali-DatePicker.git - Add the source folder to your Delphi Library Path:
Tools > Options > Language > Delphi Options > Library > Library Path - Ensure the following units are available in your project:
uses Jalali.DatePicker, Jalali.Calendar, Jalali.CalendarCore; - The component will appear in the Tool Palette under the appropriate category.
📖 Quick Start
Design-Time
Drop TJalaliDatePicker onto your form and configure it via the Object Inspector:
object JalaliDatePicker1: TJalaliDatePicker
Left = 24
Top = 24
Width = 140
Height = 24
DateFormat = jdfYYYYMMDD
ValueMode = vmJalali
UseTodayIfEmpty = False
TabStop = True
endRun-Time
// Set date programmatically
JalaliDatePicker1.Date.Year := 1403;
JalaliDatePicker1.Date.Month := 6;
JalaliDatePicker1.Date.Day := 15;
// Or assign from string
JalaliDatePicker1.Value := '1403/06/15';
// Retrieve as TDateTime (auto-converts to Gregorian)
var
Dt: TDateTime;
begin
Dt := JalaliDatePicker1.DateTime;
end;⚙️ Properties
| Property | Type | Default | Description |
|---|---|---|---|
Date |
TJalaliDate |
Today | The selected Jalali date |
DateTime |
TDateTime |
0 |
Equivalent Gregorian date/time |
Value |
string |
'' |
Textual date value in the selected format |
IsEmpty |
Boolean |
True |
Whether the date is empty |
DateFormat |
TJalaliDateFormat |
jdfYYYYMMDD |
Display format (YYYY/MM/DD, YY/MM/DD, YYYY-MM-DD) |
ValueMode |
TDateValueMode |
vmJalali |
Output mode: Jalali or Gregorian |
UseTodayIfEmpty |
Boolean |
False |
Defaults to today's date when empty |
SelectedPart |
TDateSelectPart |
dspYear |
Currently selected segment (Year/Month/Day) |
DropDownWidth |
Integer |
0 |
Dropdown width (0 = auto) |
Images |
TCustomImageList |
nil |
Image list for the drop-down button |
ImageIndex |
TImageIndex |
-1 |
Image index within Images |
DropIcon |
TPicture |
nil |
Custom picture for the drop-down button |
ValidationErrorDisplay |
Boolean |
True |
Enables validation error handling |
DataSource |
TDataSource |
nil |
Data source for Data-Aware binding |
DataField |
string |
'' |
Linked field name |
🎭 Events
| Event | Description |
|---|---|
OnChange |
Fires when the user changes the date |
OnValidationError |
Fires when invalid text is entered. Provides InvalidText and KeepFocus parameters. |
Validation Error Example
procedure TForm1.JalaliDatePicker1ValidationError(Sender: TObject;
const InvalidText: string; var KeepFocus: Boolean);
begin
ShowMessage('Invalid date entered: ' + InvalidText);
KeepFocus := True; // Keep focus on the control
end;⌨️ Keyboard Shortcuts
| Key | Action |
|---|---|
↑ |
Increment the selected part |
↓ |
Decrement the selected part |
← |
Move to previous part (Day → Month → Year) |
→ |
Move to next part (Year → Month → Day) |
Alt + ↓ |
Open / Close the dropdown calendar |
Tab |
Validate input and move to next control |
Backspace |
Clear current part or move to previous part |
0-9 |
Direct numeric input for the selected part |
🖱️ Mouse Interaction
| Action | Behavior |
|---|---|
| Click Icon | Toggle dropdown open/close |
| Click Year/Month/Day | Select that segment for editing |
| Mouse Wheel | Increment/decrement the active segment |
| Click Outside | Automatically close the dropdown |
📅 Date Formats
type
TJalaliDateFormat = (
jdfYYYYMMDD, // 1403/06/15
jdfYYMMDD, // 03/06/15
jdfYYYYMMDD_Dash // 1403-06-15
);🎨 Icon Customization
Using ImageList
JalaliDatePicker1.Images := ImageList1;
JalaliDatePicker1.ImageIndex := 0;Using TPicture
JalaliDatePicker1.DropIcon.LoadFromFile('calendar.png');Default Icon
If no custom image is assigned, a professional built-in calendar icon is rendered automatically.
🔗 Data-Aware Usage
// Bind to a dataset
JalaliDatePicker1.DataSource := DataSource1;
JalaliDatePicker1.DataField := 'BirthDate'; // ftDate or ftDateTime
// Store as Gregorian in the database while displaying Jalali
JalaliDatePicker1.ValueMode := vmMiladi;🛡️ Safety & Stability
- Secure Hooking: Uses official
SetWindowSubclassAPI instead of rawWindowProcmanipulation - Thread-Specific Mouse Hook: Detects outside clicks without interfering with other application threads
- Proper Cleanup:
TFieldDataLinkand dropdown forms are correctly freed in the destructor - Multi-Instance Safe: Multiple pickers can coexist on the same form without conflicts
📋 Requirements
| Item | Version |
|---|---|
| Del phi | 12.3 |
| Platform | Windows 32-bit / 64-bit (VCL) |
| Dependencies | Jalali.Calendar, Jalali.CalendarCore |
🖼️ Preview
🤝 Contributing
Contributions are welcome! Please open an Issue to report bugs or request new features.
📜 License
This project is licensed under the MIT License. See the LICENSE file for details.
👤 Author
AF Software
📧 AFSoft2010@gmail.com
🌐 github.com/faridfhm
If you found this project useful, please consider giving it a ⭐!

