import {Component} from '@angular/core';
import {NgbDate} from './dp/ngb-date';
const now = new Date();
@Component({
selector: 'my-app',
styles: [`
.day {
text-align: center;
padding: 0.25rem 0.35rem;
border-radius: 1rem;
background-color: lightgoldenrodyellow;
}
.day.odd {
background-color: lightblue;
}
.icon {
width: 2rem;
height: 2rem;
}
.day.selected, .day.selected:hover {
background-color: red;
}
.day.greyed {
color: lightgray;
}
.day:hover {
background-color: lightsalmon;
cursor: pointer;
}
`],
templateUrl: 'app/main.html'
})
export class AppComponent {
WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
date = {year: 2015, month: 2};
minDate = {year: 2014, month: 5, date: 10};
maxDate = {year: 2018, month: 5, date: 10};
showNavigation = true;
showWeekNumbers = false;
showWeekdays = true;
firstDayOfWeek = 1;
model1 = null;
model2 = null;
setDate() {
this.model1 = {year: now.getFullYear(), month: now.getMonth(), date: now.getDate()};
}
markDisabled(day: {year: number, month: number, date: number}): boolean {
let today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
let date = new Date(day.year, day.month, day.date);
return date < today;
}
markDisabled2(date: {year: number, month: number, date: number}): boolean {
return date.date <= 3;
}
}
<!DOCTYPE html>
<html>
<head>
<title>NgbDatepicker WIP</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://v4-alpha.getbootstrap.com/dist/css/bootstrap.min.css" />
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="https://npmcdn.com/core-js/client/shim.min.js"></script>
<script src="https://npmcdn.com/zone.js@0.6.12?main=browser"></script>
<script src="https://npmcdn.com/reflect-metadata@0.1.3"></script>
<script src="https://npmcdn.com/systemjs@0.19.27/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body class="container">
<my-app>Loading...</my-app>
</body>
</html>
<!--
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->
/**
* PLUNKER VERSION (based on systemjs.config.js in angular.io)
* System configuration for Angular 2 samples
* Adjust as necessary for your application needs.
*/
(function(global) {
var ngVer = '@2.0.0-rc.5'; // lock in the angular package version; do not let it float to current!
//map tells the System loader where to look for things
var map = {
'app': 'app',
'@angular': 'https://npmcdn.com/@angular', // sufficient if we didn't pin the version
'@angular/forms': 'https://npmcdn.com/@angular/forms@0.3.0',
'angular2-in-memory-web-api': 'https://npmcdn.com/angular2-in-memory-web-api', // get latest
'rxjs': 'https://npmcdn.com/rxjs@5.0.0-beta.6',
'ts': 'https://npmcdn.com/plugin-typescript@4.0.10/lib/plugin.js',
'typescript': 'https://npmcdn.com/typescript@1.8.10/lib/typescript.js',
};
//packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'bootstrap.ts', defaultExtension: 'ts' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
};
var ngPackageNames = [
'common',
'compiler',
'core',
'http',
'platform-browser',
'platform-browser-dynamic',
'router-deprecated',
'upgrade',
];
// Add map entries for each angular package
// only because we're pinning the version with `ngVer`.
ngPackageNames.forEach(function(pkgName) {
map['@angular/'+pkgName] = 'https://npmcdn.com/@angular/' + pkgName + ngVer;
});
// Add package entries for angular packages
ngPackageNames.forEach(function(pkgName) {
// Bundled (~40 requests):
packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
// Individual files (~300 requests):
//packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
packages['@angular/forms'] = { main: 'index.js', defaultExtension: 'js' };
var config = {
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts',
typescriptOptions: {
tsconfig: true
},
meta: {
'typescript': {
"exports": "ts"
}
},
map: map,
packages: packages
}
System.config(config);
})(this);
/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
<div class="container">
<p>Standard template, disabled dates:</p>
<ngb-datepicker #dp
[showNavigation]="showNavigation"
[showWeekNumbers]="showWeekNumbers"
[showWeekdays]="showWeekdays"
[firstDayOfWeek]="firstDayOfWeek"
[minDate]="minDate"
[maxDate]="maxDate"
[markDisabled]="markDisabled"
[(ngModel)]="model1">
</ngb-datepicker>
<div>Model: {{ model1 | json }}</div>
<button class="btn btn-sm btn-primary" (click)="setDate()">Select Today</button>
<button class="btn btn-sm btn-primary" (click)="dp.navigateTo()">Show current month</button>
<hr/>
<p>Custom date templates, disabled dates:</p>
<template #tpl let-day="day" let-month="month" let-selected="selected">
<div *ngIf="day.date.date !== 13 && !day.disabled"
class="day"
[class.odd]="day.date.date % 2 === 0"
[class.selected]="selected"
[class.greyed]="day.date.month !== month.number">{{ day.date.date }}
</div>
<img class="icon" *ngIf="day.date.date === 13" [src]="'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/URSS-Russian_aviation_red_star.svg/200px-URSS-Russian_aviation_red_star.svg.png'">
</template>
<ngb-datepicker
[startDate]="date"
[showNavigation]="showNavigation"
[showWeekNumbers]="showWeekNumbers"
[showWeekdays]="showWeekdays"
[firstDayOfWeek]="firstDayOfWeek"
[minDate]="minDate"
[maxDate]="maxDate"
[dayTemplate]="tpl"
[markDisabled]="markDisabled2"
[(ngModel)]="model2">
</ngb-datepicker>
<div>Model: {{ model2 | json }}</div>
<hr/>
<div>
<label>
<input type="checkbox" [(ngModel)]="showNavigation"> Show navigation
</label>
</div>
<div>
<label>
<input type="checkbox" [(ngModel)]="showWeekNumbers"> Show week numbers
</label>
</div>
<div>
<label>
<input type="checkbox" [(ngModel)]="showWeekdays"> Show weekdays
</label>
</div>
<div>
<label>
First day of week
<select [(ngModel)]="firstDayOfWeek">
<option *ngFor="let w of WEEKDAYS; let i = index;" [value]="i">{{ w }}</option>
</select>
</label>
</div>
</div>
import {NgModule} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserModule} from '@angular/platform-browser';
import {FormsModule} from '@angular/forms';
import {NgbDatepickerModule} from './dp/datepicker.module';
import {AppComponent} from './main';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
NgbDatepickerModule,
FormsModule
],
bootstrap: [AppComponent]
})
export class AppModule {
}
platformBrowserDynamic().bootstrapModule(AppModule);
import {Component, Input, OnChanges, SimpleChanges, TemplateRef, forwardRef, OnInit} from '@angular/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms';
import {NgbCalendar} from './ngb-calendar';
import {NgbDate} from './ngb-date';
import {NgbDatepickerService} from './datepicker-service';
import {MonthViewModel, DayTemplateContext, NavigationEvent} from './datepicker-view-model';
import {toInteger} from '../util';
const NGB_DATEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgbDatepicker),
multi: true
};
/**
* A lightweight and highly configurable datepicker directive
*/
@Component({
exportAs: 'ngbDatepicker',
selector: 'ngb-datepicker',
template: `
<template #dt let-day="day" let-month="month" let-selected="selected">
<div ngb-datepicker-day-view [day]="day" [month]="month" [selected]="selected"></div>
</template>
<table>
<tbody *ngIf="showNavigation" ngb-datepicker-navigation
[date]="_date"
[minDate]="_minDate"
[maxDate]="_maxDate"
[type]="navigation"
[showWeekNumbers]="showWeekNumbers"
(navigate)="onNavigateEvent($event)"
(select)="onNavigateDateSelect($event)">
</tbody>
<tbody ngb-datepicker-month-view
[month]="month"
[selectedDate]="model"
[dayTemplate]="dayTemplate || dt"
[showWeekdays]="showWeekdays"
[showWeekNumbers]="showWeekNumbers"
(select)="onDateSelect($event)">
</tbody>
</table>
`,
providers: [NGB_DATEPICKER_VALUE_ACCESSOR]
})
export class NgbDatepicker implements OnChanges,
OnInit, ControlValueAccessor {
_date: NgbDate;
_minDate: NgbDate;
_maxDate: NgbDate;
month: MonthViewModel;
model: NgbDate;
/**
* Reference for the custom template for the day display
*/
@Input() dayTemplate: TemplateRef<DayTemplateContext>;
/**
* First day of the week, 0=Sun, 1=Mon, etc.
*/
@Input() firstDayOfWeek = 1;
/**
* Callback to mark a given date as disabled
*/
@Input() markDisabled: (date: {year: number, month: number, date: number}) => boolean;
/**
* Min date for the navigation. Works only with navigation type 'select'
*/
@Input() minDate: {year: number, month: number, date: number};
/**
* Max date for the navigation. Works only with navigation type 'select'
*/
@Input() maxDate: {year: number, month: number, date: number};
/**
* Navigation type. 'select' is a default one and uses selectboxes fot month and year. Other types might be supported
* in future
*/
@Input() navigation = 'select';
/**
* Whether to display navigation or not
*/
@Input() showNavigation = true;
/**
* Whether to display days of the week
*/
@Input() showWeekdays = true;
/**
* Whether to display week numbers
*/
@Input() showWeekNumbers = false;
/**
* Date to open calendar with. If nothing provided, calendar will open with current month.
* Use 'navigateTo(date)' as an alternative
*/
@Input() startDate: {year: number, month: number};
onChange = (_: any) => {};
onTouched = () => {};
constructor(private _service: NgbDatepickerService, private _calendar: NgbCalendar) {}
/**
* Navigates current view to provided date. If nothing provided calendat will open current month.
* Use 'date' input as an alternative
*/
navigateTo(date?: {year: number, month: number}) {
this._setViewWithinLimits(date ? NgbDate.from(date) : this._calendar.getToday());
this._updateData();
}
ngOnInit() {
this._maxDate = NgbDate.from(this.maxDate);
this._minDate = NgbDate.from(this.minDate);
if ((!this._maxDate || !this._minDate) && this.navigation === 'select') {
throw new Error(`Both 'maxDate' and 'minDate' must be provided for navigation type 'select'`);
}
if (this._minDate && this._maxDate && this._maxDate.before(this._minDate)) {
throw new Error(`'maxDate' should be greater than 'minDate'`);
}
}
ngOnChanges(changes: SimpleChanges) {
this._maxDate = NgbDate.from(this.maxDate);
this._minDate = NgbDate.from(this.minDate);
this.navigateTo(this.startDate);
}
/**
* @internal
*/
onDateSelect(date: NgbDate) {
this._setViewWithinLimits(date);
this.onTouched();
this.writeValue(date);
this.onChange({year: date.year, month: date.month, date: date.date});
// switch current month
if (this._date.month !== this.month.number) {
this._updateData();
}
}
/**
* @internal
*/
onNavigateDateSelect(date: NgbDate) {
this._setViewWithinLimits(date);
this._updateData();
}
/**
* @internal
*/
onNavigateEvent(event: NavigationEvent) {
switch (event) {
case NavigationEvent.PREV:
this._setViewWithinLimits(this._calendar.getPrevMonth(this._date));
break;
case NavigationEvent.NEXT:
this._setViewWithinLimits(this._calendar.getNextMonth(this._date));
break;
}
this._updateData();
}
/**
* @internal
*/
registerOnChange(fn: (value: any) => any): void { this.onChange = fn; }
/**
* @internal
*/
registerOnTouched(fn: () => any): void { this.onTouched = fn; }
/**
* @internal
*/
writeValue(value) { this.model = value ? new NgbDate(value.year, value.month, value.date) : null; }
private _setViewWithinLimits(date: NgbDate) {
if (this._minDate && date.before(this._minDate)) {
this._date = new NgbDate(this._minDate.year, this._minDate.month, 1);
} else if (this._maxDate && date.after(this._maxDate)) {
this._date = new NgbDate(this._maxDate.year, this._maxDate.month, 1);
} else {
this._date = new NgbDate(date.year, date.month, 1);
}
}
private _updateData() {
this.month = this._service.generateMonthViewModel(
this._date, this._minDate, this._maxDate, toInteger(this.firstDayOfWeek), this.markDisabled);
}
}
import {Component, Input, TemplateRef, Output, EventEmitter} from '@angular/core';
import {MonthViewModel, DayViewModel, DayTemplateContext} from './datepicker-view-model';
import {NgbDate} from './ngb-date';
import {NgbDatepickerI18n} from './datepicker-i18n';
@Component({
selector: '[ngb-datepicker-month-view]',
styles: [`
.weekday {
padding-bottom: 0.25rem;
}
.weeknumber {
}
.day {
padding: 0;
height: 100%;
cursor: pointer;
}
.day.disabled {
cursor: not-allowed;
}
`],
template: `
<tr *ngIf="showWeekdays">
<td *ngIf="showWeekNumbers"></td>
<td *ngFor="let w of month.weekdays" class="weekday text-xs-center font-weight-bold">{{ i18n.getWeekdayName(w) }}</td>
</tr>
<tr *ngFor="let week of month.weeks">
<td *ngIf="showWeekNumbers" class="weeknumber small text-xs-center">{{ week.number }}</td>
<td *ngFor="let day of week.days" (click)="doSelect(day)" class="day" [class.disabled]="day.disabled">
<template [ngTemplateOutlet]="dayTemplate"
[ngOutletContext]="{day: day, month: month, selected: selectedDate && selectedDate.equals(day.date)}"></template>
</td>
</tr>
`
})
export class NgbDatepickerMonthView {
@Input() month: MonthViewModel;
@Input() selectedDate: NgbDate;
@Input() dayTemplate: TemplateRef<DayTemplateContext>;
@Input() showWeekdays;
@Input() showWeekNumbers;
@Output() select = new EventEmitter<NgbDate>();
constructor(public i18n: NgbDatepickerI18n) {}
doSelect(day: DayViewModel) {
if (!day.disabled) {
this.select.emit(NgbDate.from(day.date));
}
}
}
export function toInteger(value: any): number {
return parseInt(`${value}`, 10);
}
export function toString(value: any): string {
return (value !== undefined && value !== null) ? `${value}` : '';
}
export function getValueInRange(value: number, max: number, min = 0): number {
return Math.max(Math.min(value, max), min);
}
export function isString(value: any): boolean {
return typeof value === 'string';
}
export function isNumber(value: any): boolean {
return !isNaN(toInteger(value));
}
export function padNumber(value: number) {
if (isNumber(value)) {
return `0${value}`.slice(-2);
} else {
return '';
}
}
export function regExpEscape(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
import {Component, Input, Output, EventEmitter} from '@angular/core';
import {NavigationEvent} from './datepicker-view-model';
import {NgbDate} from './ngb-date';
import {NgbDatepickerI18n} from './datepicker-i18n';
import {NgbCalendar} from './ngb-calendar';
@Component({
selector: '[ngb-datepicker-navigation]',
styles: [`
td {
text-align: center;
padding-bottom: 0.25rem;
}
`],
template: `
<tr>
<td>
<button (click)="doNavigate(navigation.PREV)" class="btn btn-sm btn-secondary btn-block" [disabled]="prevDisabled()"><</button>
</td>
<td [attr.colspan]="showWeekNumbers ? 6 : 5">
<ngb-datepicker-navigation-select *ngIf="type === 'select'"
[date]="date"
[minYear]="minDate.year"
[maxYear]="maxDate.year"
(select)="selectDate($event)">
</ngb-datepicker-navigation-select>
</td>
<td>
<button (click)="doNavigate(navigation.NEXT)" class="btn btn-sm btn-secondary btn-block" [disabled]="nextDisabled()">></button>
</td>
</tr>
`
})
export class NgbDatepickerNavigation {
navigation = NavigationEvent;
@Input() type: string;
@Input() showWeekNumbers: boolean;
@Input() date: NgbDate;
@Input() minDate: NgbDate;
@Input() maxDate: NgbDate;
@Output() navigate = new EventEmitter<NavigationEvent>();
@Output() select = new EventEmitter<NgbDate>();
constructor(public i18n: NgbDatepickerI18n, private _calendar: NgbCalendar) {}
doNavigate(event: NavigationEvent) { this.navigate.emit(event); }
nextDisabled() { return !this.maxDate ? false : this._calendar.getNextMonth(this.date).after(this.maxDate); }
prevDisabled() { return !this.minDate ? false : this._calendar.getPrevMonth(this.date).before(this.minDate); }
selectDate(date: NgbDate) { this.select.emit(date); }
}
import {NgbCalendar} from './ngb-calendar';
import {NgbDate} from './ngb-date';
import {MonthViewModel, DayViewModel} from './datepicker-view-model';
import {Injectable} from '@angular/core';
@Injectable()
export class NgbDatepickerService {
constructor(private _calendar: NgbCalendar) {}
generateMonthViewModel(
date: NgbDate, minDate: NgbDate, maxDate: NgbDate, firstDayOfWeek: number,
markDisabled: (date: NgbDate) => boolean): MonthViewModel {
const month: MonthViewModel = {number: date.month, year: date.year, weeks: [], weekdays: []};
date = this._getFirstViewDate(date, firstDayOfWeek);
// month has weeks
for (let w = 0; w < this._calendar.getWeeksPerMonth(); w++) {
const days: DayViewModel[] = [];
// week has days
for (let d = 0; d < this._calendar.getDaysPerWeek(); d++) {
if (w === 0) {
month.weekdays.push(this._calendar.getWeekday(date));
}
const newDate = new NgbDate(date.year, date.month, date.date);
let disabled = (minDate && newDate.before(minDate)) || (maxDate && newDate.after(maxDate));
if (!disabled && markDisabled) {
disabled = markDisabled(newDate);
}
days.push({date: {year: date.year, month: date.month, date: date.date}, disabled: disabled});
date = this._calendar.getNextDate(date);
}
month.weeks.push(
{number: this._calendar.getWeekNumber(days.map(day => NgbDate.from(day.date)), firstDayOfWeek), days: days});
}
return month;
}
private _getFirstViewDate(date: NgbDate, firstDayOfWeek: number): NgbDate {
const currentMonth = date.month;
let today = new NgbDate(date.year, date.month, date.date);
let yesterday = this._calendar.getPrevDate(today);
const firstDayOfCurrentMonthIsAlsoFirstDayOfWeek =
() => { return today.month !== yesterday.month && firstDayOfWeek === this._calendar.getWeekday(today); };
const reachedTheFirstDayOfTheLastWeekOfPreviousMonth =
() => { return today.month !== currentMonth && firstDayOfWeek === this._calendar.getWeekday(today); };
// going back in time
while (!reachedTheFirstDayOfTheLastWeekOfPreviousMonth() && !firstDayOfCurrentMonthIsAlsoFirstDayOfWeek()) {
today = new NgbDate(yesterday.year, yesterday.month, yesterday.date);
yesterday = this._calendar.getPrevDate(yesterday);
}
return today;
}
}
import {NgbDate} from './ngb-date';
export type DayViewModel = {
date: {year: number, month: number, date: number},
disabled: boolean
}
export type WeekViewModel = {
number: number,
days: DayViewModel[]
}
export type MonthViewModel = {
number: number,
year: number,
weeks: WeekViewModel[],
weekdays: number[]
};
export type DayTemplateContext = {
day: DayViewModel,
month: MonthViewModel,
selected: boolean
};
export enum NavigationEvent {
PREV,
NEXT
}
import {NgbDate} from './ngb-date';
import {Injectable} from '@angular/core';
/**
* Default implementation of a Gregorian calendar
*/
@Injectable()
export class NgbCalendar {
private toDate(date: NgbDate) { return new Date(date.year, date.month, date.date); }
private fromDate(jsDate: Date) { return new NgbDate(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate()); }
getDaysPerWeek() { return 7; }
getMonths() { return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; }
getWeeksPerMonth() { return 6; }
getWeekday(date: NgbDate) {
let jsDate = this.toDate(date);
return jsDate.getDay();
}
getNextDate(date: NgbDate): NgbDate {
let jsDate = this.toDate(date);
jsDate.setDate(jsDate.getDate() + 1);
return this.fromDate(jsDate);
}
getPrevDate(date: NgbDate): NgbDate {
let jsDate = this.toDate(date);
jsDate.setDate(jsDate.getDate() - 1);
return this.fromDate(jsDate);
}
getNextMonth(date: NgbDate): NgbDate {
let jsDate = this.toDate(date);
jsDate = new Date(jsDate.getFullYear(), jsDate.getMonth() + 1, 1);
return this.fromDate(jsDate);
}
getPrevMonth(date: NgbDate): NgbDate {
let jsDate = this.toDate(date);
jsDate = new Date(jsDate.getFullYear(), jsDate.getMonth() - 1, 1);
return this.fromDate(jsDate);
}
getWeekNumber(week: NgbDate[], firstDayOfWeek: number) {
const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
let date = week[thursdayIndex];
const jsDate = this.toDate(date);
jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
const time = jsDate.getTime();
jsDate.setMonth(0); // Compare with Jan 1
jsDate.setDate(1);
return Math.floor(Math.round((time - jsDate.getTime()) / 86400000) / 7) + 1;
}
getToday(): NgbDate { return this.fromDate(new Date()); }
}
export class NgbDate {
static from(date: {year: number, month: number, date?: number}) {
return date ? new NgbDate(date.year, date.month, date.date ? date.date : 1) : null;
}
constructor(public year: number, public month: number, public date: number) {}
equals(other: NgbDate) {
return other && this.year === other.year && this.month === other.month && this.date === other.date;
}
before(other: NgbDate) {
return !other ? false : this.year === other.year ?
this.month === other.month ? this.date === other.date ? false : this.date < other.date :
this.month < other.month :
this.year < other.year;
}
after(other: NgbDate) {
return !other ? false : this.year === other.year ?
this.month === other.month ? this.date === other.date ? false : this.date > other.date :
this.month > other.month :
this.year > other.year;
}
}
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {NgbDatepicker} from './datepicker';
import {NgbDatepickerMonthView} from './datepicker-month-view';
import {NgbDatepickerNavigation} from './datepicker-navigation';
import {FormsModule} from '@angular/forms';
import {NgbDatepickerDayView} from './datepicker-day-view';
import {NgbDatepickerI18n} from './datepicker-i18n';
import {NgbCalendar} from './ngb-calendar';
import {NgbDatepickerService} from './datepicker-service';
import {NgbDatepickerNavigationSelect} from './datepicker-navigation-select';
@NgModule({
declarations: [
NgbDatepicker, NgbDatepickerMonthView, NgbDatepickerNavigation, NgbDatepickerNavigationSelect, NgbDatepickerDayView
],
exports: [NgbDatepicker],
imports: [CommonModule, FormsModule],
providers: [NgbDatepickerI18n, NgbCalendar, NgbDatepickerService]
})
export class NgbDatepickerModule {
}
import {Component, Input} from '@angular/core';
import {MonthViewModel, DayViewModel} from './datepicker-view-model';
@Component({
selector: '[ngb-datepicker-day-view]',
styles: [`
:host {
text-align: center;
padding: 0.185rem 0.25rem;
border-radius: 0.25rem;
}
`],
host: {'[class.bg-primary]': 'selected', '[class.text-muted]': 'day.date.month !== month.number || day.disabled'},
template: `{{ day.date.date }}`
})
export class NgbDatepickerDayView {
@Input() month: MonthViewModel;
@Input() day: DayViewModel;
@Input() selected: boolean;
}
import {Component, Input, Output, EventEmitter, OnChanges, SimpleChanges} from '@angular/core';
import {NgbDate} from './ngb-date';
import {toInteger} from '../util';
import {NgbDatepickerI18n} from './datepicker-i18n';
import {NgbCalendar} from './ngb-calendar';
@Component({
selector: 'ngb-datepicker-navigation-select',
styles: [`
select {
/* to align with btn-sm */
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
line-height: 1.25;
width: 50%;
}
`],
template: `
<select class="custom-select d-inline-block" [value]="date.month" (change)="changeMonth($event.target.value)">
<option *ngFor="let m of months" [value]="m">{{ i18n.getMonthName(m) }}</option>
</select>` +
`<select class="custom-select d-inline-block" [value]="date.year" (change)="changeYear($event.target.value)">
<option *ngFor="let y of years" [value]="y">{{ y }}</option>
</select>
` // template needs to be formatted in a certain way so we don't add empty text nodes
})
export class NgbDatepickerNavigationSelect implements OnChanges {
months: number[];
years: number[] = [];
@Input() date: NgbDate;
@Input() minYear: number;
@Input() maxYear: number;
@Output() select = new EventEmitter<NgbDate>();
constructor(public i18n: NgbDatepickerI18n, calendar: NgbCalendar) { this.months = calendar.getMonths(); }
ngOnChanges(changes: SimpleChanges) {
if (changes['maxYear'] || changes['minYear']) {
this._generateYears();
}
}
changeMonth(month: string) { this.select.emit(new NgbDate(this.date.year, toInteger(month), 1)); }
changeYear(year: string) { this.select.emit(new NgbDate(toInteger(year), this.date.month, 1)); }
private _generateYears() {
this.years = Array.from({length: this.maxYear - this.minYear + 1}, (e, i) => this.minYear + i);
}
}
import {Injectable} from '@angular/core';
const WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
@Injectable()
export class NgbDatepickerI18n {
getWeekdayName(weekday: number): string { return WEEKDAYS[weekday]; }
getMonthName(month: number): string { return MONTHS[month]; }
}