UNPKG

gramli-angular-mydatepicker

Version:

A highly configurable Angular datepicker and date range picker with no external dependencies. Lightweight, flexible, and feature-rich.

426 lines (317 loc) 12.4 kB
# angular-mydatepicker [![Build&Test](https://github.com/Gramli/angular-mydatepicker/actions/workflows/build_and_test.yml/badge.svg)](https://github.com/Gramli/angular-mydatepicker/actions/workflows/build_and_test.yml) [![npm version](https://badge.fury.io/js/gramli-angular-mydatepicker.svg)](https://www.npmjs.com/package/gramli-angular-mydatepicker) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) A highly configurable Angular datepicker and date range picker with no external dependencies. Lightweight, flexible, and feature-rich. **[Demo App](https://github.com/Gramli/angular-mydatepicker/tree/master/example)** | **[API Documentation](#api-reference)** ## Features - **Zero dependencies** - Pure Angular implementation - **Dual modes** - Single date or date range selection - **Flexible display** - Popup or inline mode - **Rich localization** - 40+ built-in locales with easy customization - **Keyboard navigation** - Full accessibility support - **RTL support** - Right-to-left language compatibility - **Smooth animations** - Multiple animation styles for calendar transitions - **Highly customizable** - 50+ configuration options - **Well tested** - Comprehensive test coverage - **TypeScript** - Full type definitions included ## Installation ```bash npm install gramli-angular-mydatepicker ``` ## Quick Start ### 1. Import the module Add `AngularMyDatePickerModule` to your application module: ```typescript import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AngularMyDatePickerModule } from 'gramli-angular-mydatepicker'; @NgModule({ imports: [ BrowserModule, FormsModule, ReactiveFormsModule, AngularMyDatePickerModule ], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } ``` ### 2. Use in your component **Template-driven forms (ngModel):** ```html <input angular-mydatepicker name="mydate" [(ngModel)]="model" [options]="myOptions" #dp="angular-mydatepicker" /> ``` **Reactive forms:** ```html <input angular-mydatepicker [formControl]="myDateControl" [options]="myOptions" /> ``` **Component TypeScript:** ```typescript import { IAngularMyDpOptions, IMyDateModel } from 'gramli-angular-mydatepicker'; export class MyComponent { myOptions: IAngularMyDpOptions = { dateRange: false, dateFormat: 'dd.mm.yyyy' }; model: IMyDateModel = null; } ``` ## Compatibility | Package Version | Angular Version | |----------------|-----------------| | `21.0.x` | `21.x` | | `0.18.x` | `20.x` | | `0.17.x` | `19.x` | | `0.16.x` | `18.x` | | `0.15.x` | `17.x` | > [!NOTE] > This project was originally forked from [nodro7/angular-mydatepicker](https://github.com/nodro7/angular-mydatepicker). For older versions, visit the original repository. ## Usage Examples ### Basic Date Picker ```typescript // component.ts import { IAngularMyDpOptions } from 'gramli-angular-mydatepicker'; myOptions: IAngularMyDpOptions = { dateFormat: 'dd.mm.yyyy', firstDayOfWeek: 'mo' }; ``` ```html <!-- template.html --> <input angular-mydatepicker [(ngModel)]="model" [options]="myOptions" /> ``` ### Date Range Picker ```typescript myRangeOptions: IAngularMyDpOptions = { dateRange: true, dateFormat: 'dd.mm.yyyy' }; ``` ### Inline Mode ```html <input type="hidden" angular-mydatepicker [(ngModel)]="model" [options]="{inline: true}" /> ``` ### With Locale ```typescript myOptions: IAngularMyDpOptions = { dateFormat: 'dd/mm/yyyy' }; ``` ```html <input angular-mydatepicker [(ngModel)]="model" [options]="myOptions" locale="fr" /> ``` For complete examples, see: - [ngModel example](https://github.com/gramli/angular-mydatepicker/tree/master/example/app/date-picker-ngmodel) - [Reactive forms example](https://github.com/gramli/angular-mydatepicker/tree/master/example/app/date-picker-reactive-forms) - [Inline mode example](https://github.com/gramli/angular-mydatepicker/tree/master/example/app/date-picker-inline) ## API Reference ### Configuration Options The datepicker accepts an `options` attribute of type [`IAngularMyDpOptions`](https://github.com/gramli/angular-mydatepicker/blob/master/projects/angular-mydatepicker/src/lib/interfaces/my-options.interface.ts) with 50+ configuration options. #### Core Options | Option | Type | Default | Description | |--------|------|---------|-------------| | `dateRange` | `boolean` | `false` | Enable date range picker mode | | `inline` | `boolean` | `false` | Display calendar inline (set input `type="hidden"`) | | `dateFormat` | `string` | `'yyyy-mm-dd'` | Date format (e.g., `'dd.mm.yyyy'`, `'mm/dd/yyyy'`) | | `defaultView` | `DefaultView` | `date` | Initial calendar view: `date`, `month`, or `year` | | `firstDayOfWeek` | `string` | `'mo'` | First day of week: `mo`, `tu`, `we`, `th`, `fr`, `sa`, `su` | | `showWeekNumbers` | `boolean` | `false` | Display ISO week numbers | | `selectorHeight` | `string` | `'266px'` | Calendar height | | `selectorWidth` | `string` | `'266px'` | Calendar width | #### Date Constraints | Option | Type | Description | |--------|------|-------------| | `disableUntil` | `IMyDate` | Disable all dates before this date | | `disableSince` | `IMyDate` | Disable all dates after this date | | `disableDates` | `IMyDate[]` | Disable specific dates | | `disableDateRanges` | `IMyDateRange[]` | Disable date ranges | | `disableWeekends` | `boolean` | Disable Saturdays and Sundays | | `disableWeekdays` | `string[]` | Disable specific weekdays (e.g., `['tu', 'we']`) | | `enableDates` | `IMyDate[]` | Enable specific dates (overrides disable rules) | #### Styling & Highlighting | Option | Type | Description | |--------|------|-------------| | `markDates` | `IMyMarkedDates[]` | Mark dates with colors or custom styles | | `markWeekends` | `IMyMarkedDate` | Highlight weekends with custom color | | `highlightDates` | `IMyDate[]` | Highlight specific dates in red | | `sunHighlight` | `boolean` | Highlight Sundays in red | | `satHighlight` | `boolean` | Highlight Saturdays in red | | `stylesData` | `IMyStyles` | Override default styles | #### Animation & Behavior | Option | Type | Default | Description | |--------|------|---------|-------------| | `calendarAnimation` | `IMyCalendarAnimation` | `None` | Open/close animation: `None`, `Fade`, `ScaleTop`, `ScaleCenter`, `Rotate`, `FlipDiagonal`, `Own` | | `viewChangeAnimation` | `boolean` | `true` | Enable view transition animations | | `closeSelectorOnDateSelect` | `boolean` | `true` | Close calendar after date selection | | `closeSelectorOnDocumentClick` | `boolean` | `true` | Close calendar on outside click | | `rtl` | `boolean` | `false` | Enable right-to-left mode | #### Accessibility | Option | Type | Default | |--------|------|---------| | `ariaLabelPrevMonth` | `string` | `'Previous Month'` | | `ariaLabelNextMonth` | `string` | `'Next Month'` | For the complete list of options, see [`IAngularMyDpOptions`](https://github.com/gramli/angular-mydatepicker/blob/master/projects/angular-mydatepicker/src/lib/interfaces/my-options.interface.ts). ### Locales The datepicker supports 40+ locales out of the box. Set the `locale` attribute to an [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code: ```html <input angular-mydatepicker [(ngModel)]="model" locale="fr" /> ``` #### Supported Locales `en`, `fr`, `fr-ch`, `ja`, `fi`, `es`, `hu`, `sv`, `nl`, `ru`, `uk`, `uz`, `no`, `tr`, `pt-br`, `pt`, `de`, `de-ch`, `it`, `it-ch`, `pl`, `my`, `ms`, `sk`, `sl`, `zh-cn`, `he`, `ro`, `ca`, `id`, `en-au`, `en-gb`, `am-et`, `cs`, `el`, `kk`, `th`, `ko-kr`, `da`, `lt`, `vi`, `bn`, `bg`, `hr`, `ar`, `is`, `tw`, `lv`, `et` > [!TIP] > To add a new locale, submit a PR updating the [locale service](https://github.com/gramli/angular-mydatepicker/blob/master/projects/angular-mydatepicker/src/lib/services/angular-mydatepicker.locale.service.ts). ### Default Month Control which month is displayed when the calendar opens: ```typescript // String format defaultMonth: '08-2019' // Object format defaultMonth: { defMonth: '08/2019', overrideSelection: true // Show this month even if a date is selected } ``` The calendar opens to: 1. The selected date's month (or begin date in range mode) 2. The `defaultMonth` if specified (or if `overrideSelection: true`) 3. The current month if neither above applies ### Directive Methods Access directive methods using a template reference variable: ```html <input angular-mydatepicker #dp="angular-mydatepicker" /> ``` | Method | Description | |--------|-------------| | `dp.openCalendar()` | Open the calendar | | `dp.closeCalendar()` | Close the calendar | | `dp.toggleCalendar()` | Toggle calendar (returns `true` if opened) | | `dp.clearDate()` | Clear the selected date/range | | `dp.isDateValid()` | Check if current input is valid | | `dp.headerAction(action)` | Trigger header button action | | `dp.setHostValue(value)` | Set input box value | ### Events #### dateChanged Emitted when a date is selected, cleared, or input is valid. ```typescript onDateChanged(event: IMyDateModel) { if (event.isRange) { console.log('Range:', event.dateRange); } else { console.log('Date:', event.singleDate); } } ``` **Event structure:** - `isRange`: boolean - true for date ranges - `singleDate`: `{ date, jsDate, formatted, epoc }` (when `isRange` is false) - `dateRange`: `{ beginDate, beginJsDate, beginEpoc, endDate, endJsDate, endEpoc, formatted }` (when `isRange` is true) #### inputFieldChanged Emitted on input field changes. ```typescript onInputChanged(event: IMyInputFieldChanged) { console.log('Value:', event.value); console.log('Valid:', event.valid); } ``` #### calendarViewChanged Emitted when the calendar view changes. ```typescript onViewChanged(event: IMyCalendarViewChanged) { console.log('Month:', event.month, 'Year:', event.year); } ``` #### calendarToggle Emitted when calendar opens/closes with reason code: - `1` - Calendar opened - `2` - Closed by date select - `3` - Closed by calendar button - `4` - Closed by outside click - `5` - Closed by ESC key #### rangeDateSelection Emitted in date range mode when a date is selected. ```typescript onRangeSelection(event) { console.log(event.isBegin ? 'Start date:' : 'End date:', event.formatted); } ``` #### viewActivated Emitted when calendar view changes (date/month/year). ```typescript onViewActivated(view: ActiveView) { // 1 = date view, 2 = month view, 3 = year view } ``` ## Styling Override any styles from the [default stylesheet](https://github.com/gramli/angular-mydatepicker/blob/master/projects/angular-mydatepicker/src/lib/css/angular-mydatepicker.style.css) using the `stylesData` option: ```typescript myOptions: IAngularMyDpOptions = { stylesData: { selector: 'dp1', styles: ` .dp1 .myDpMarkCurrDay { border-bottom: 2px solid #0099ff; } ` } } ``` ## Development ### Prerequisites - [Git](https://git-scm.com/) - [Node.js](https://nodejs.org/) with npm ### Setup ```bash git clone https://github.com/Gramli/angular-mydatepicker.git cd angular-mydatepicker npm install ``` ### Run Demo ```bash npm start # Navigate to http://localhost:4200 ``` ### Testing & Linting ```bash # Run tests with coverage npm run test-lib # Coverage report available in test-output/ # Run linter npm run lint-lib ``` ### Build Library ```bash npm run build-lib # Output: dist/angular-mydatepicker/ ``` ### Create Local Package ```bash npm run build-lib cd dist/angular-mydatepicker npm pack # Install in your project: # npm install path/to/gramli-angular-mydatepicker-x.y.z.tgz ``` ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. For new locales, update the [locale service](https://github.com/gramli/angular-mydatepicker/blob/master/projects/angular-mydatepicker/src/lib/services/angular-mydatepicker.locale.service.ts). ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Credits Originally created by [kekeh](https://github.com/kekeh) and [nodro7](https://github.com/nodro7). Currently maintained by [Gramli](https://github.com/Gramli).