Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to always keep the date picker open [isAlwaysOpen] = true #283

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 5 additions & 94 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,96 +1,7 @@
{
"author": "jessie",
"name": "ng2-datepicker",
"version": "2.1.6",
"main": "bundles/ng2-datepicker.umd.js",
"repository": {
"type": "git",
"url": "git+https://github.com/jkuri/ng2-datepicker.git"
},
"authors": [
"Jan Kuri <[email protected]>"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/jkuri/ng2-datepicker/issues"
},
"homepage": "https://github.com/jkuri/ng2-datepicker#readme",
"scripts": {
"clean": "rimraf dist lib bundles ./**/*.ngsummary.* ./**/*.ngfactory.* ./**/*.ngstyle.*",
"prestart": "npm run clean",
"start": "webpack-dev-server --env.dev --env.serve --progress --hot",
"start:noopen": "webpack-dev-server --env.dev --env.serve --env.noOpen",
"prestart:aot": "npm run clean",
"start:aot": "webpack-dev-server --env.aot --env.dev --env.serve --progress",
"prebuild": "npm run clean",
"build": "webpack --env.dev --progress --hide-modules",
"prebuild:aot": "npm run clean",
"build:aot": "webpack --env.dev --env.aot --progress --hide-modules",
"prebuild:prod": "npm run clean",
"build:prod": "webpack --env.prod --env.aot --progress --hide-modules -p",
"test": "karma start",
"pretest:e2e": "webdriver-manager update -- --standalone",
"test:e2e": "protractor ./protractor.conf.js",
"test:ci:e2e": "node ./e2e/run.js",
"build:dist": "webpack --config webpack.dist.js -p",
"prepublishOnly": "npm run build:dist"
},
"devDependencies": {
"@angular/animations": "^4.4.3",
"@angular/common": "^4.4.3",
"@angular/compiler": "^4.4.3",
"@angular/compiler-cli": "4.4.3",
"@angular/core": "^4.4.3",
"@angular/forms": "^4.4.3",
"@angular/http": "^4.4.3",
"@angular/platform-browser": "^4.4.3",
"@angular/platform-browser-dynamic": "^4.4.3",
"@angular/platform-server": "^4.4.3",
"@angular/router": "^4.4.3",
"@ngtools/webpack": "^1.7.1",
"@types/chalk": "^0.4.31",
"@types/jasmine": "^2.6.0",
"add-asset-html-webpack-plugin": "^2.1.2",
"angular2-template-loader": "^0.6.2",
"awesome-typescript-loader": "^3.2.3",
"bulma": "^0.5.3",
"chalk": "^2.1.0",
"circular-dependency-plugin": "^4.2.1",
"compression-webpack-plugin": "^1.0.0",
"copy-webpack-plugin": "^4.0.1",
"core-js": "^2.5.1",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"html-loader": "^0.5.1",
"html-webpack-plugin": "^2.30.1",
"jasmine": "^2.8.0",
"jasmine-spec-reporter": "^4.2.1",
"karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.0",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.4",
"node-sass": "^4.5.3",
"portfinder": "^1.0.13",
"protractor": "^5.1.2",
"raw-loader": "^0.5.1",
"rimraf": "^2.6.2",
"rxjs": "^5.4.3",
"sass-loader": "^6.0.6",
"source-map-loader": "^0.2.1",
"style-loader": "^0.18.2",
"to-string-loader": "^1.1.5",
"tree-kill": "^1.2.0",
"ts-node": "^3.3.0",
"tslint": "^5.7.0",
"typescript": "^2.5.2",
"webpack": "^3.6.0",
"webpack-dev-server": "^2.8.2",
"webpack-merge": "^4.1.0",
"zone.js": "^0.8.17"
},
"dependencies": {
"date-fns": "^1.28.5",
"ngx-slimscroll": "^3.5.2"
}
}
"version": "0.0.0",
"description": "Generated with typescript.java",
"license": "MIT"
}
7 changes: 6 additions & 1 deletion src/ng-datepicker/ng-datepicker.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,18 @@
<span class="day-name-unit" *ngFor="let name of dayNames">{{ name }}</span>
</div>
<div class="main-calendar-days">
<span class="day-unit" *ngFor="let day of days; let i = index;" [ngClass]="{ 'is-prev-month': !day.inThisMonth, 'is-today': day.isToday, 'is-selected': day.isSelected }" (click)="setDate(i)">{{ day.day }}</span>
<span class="day-unit" *ngFor="let day of days; let i = index;" [ngClass]="{ 'is-prev-month': !day.inThisMonth, 'is-today': day.isToday, 'is-selected': day.isSelected, 'is-busy': day.isBusy }" (click)="setDate(i)">{{ day.day }}</span>
</div>
</div>
<div class="main-calendar-container" *ngIf="view === 'years'">
<div class="main-calendar-years" slimScroll [options]="scrollOptions">
<span class="year-unit" *ngFor="let year of years; let i = index;" [ngClass]="{ 'is-selected': year.isThisYear }" (click)="setYear(i)">{{ year.year }}</span>
</div>
</div>
<div class="main-calendar-container" *ngIf="view === 'months'">
<div class="main-calendar-months" slimScroll [options]="scrollOptions">
<span class="month-unit" *ngFor="let month of months; let i = index;" [ngClass]="{ 'is-selected': month.isThisMonth }" (click)="setMonth(i)">{{ month.month }}</span>
</div>
</div>
</div>
</div>
13 changes: 9 additions & 4 deletions src/ng-datepicker/ng-datepicker.component.sass
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ $radius: 4px
$text: #3D495C
$text-secondary: #A4A9B1
$color: #1A91EB
$color-busy: #f5ce1e

.ngx-datepicker-position-bottom-left
top: 40px
Expand Down Expand Up @@ -81,14 +82,14 @@ $color: #1A91EB
text-transform: uppercase
text-align: center

.main-calendar-days, .main-calendar-years
.main-calendar-days, .main-calendar-years, .main-calendar-months
padding: 15px 0
width: 100%
display: inline-block
max-height: 275px
overflow: hidden

.day-unit, .year-unit
.day-unit, .year-unit, .month-unit
width: calc(100% / 7)
height: 40px
display: inline-flex
Expand All @@ -107,15 +108,19 @@ $color: #1A91EB
background: $text-secondary
color: $white

&.is-busy
background: $color-busy
color: $white

&.is-selected
background: $color
color: $white

.main-calendar-years
.main-calendar-years, .main-calendar-months
height: 210px
display: block
padding: 0

.year-unit
.year-unit, .month-unit
width: calc(100% / 3)
border-radius: 10px
66 changes: 58 additions & 8 deletions src/ng-datepicker/ng-datepicker.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
addMonths,
subMonths,
setYear,
setMonth,
eachDay,
getDate,
getMonth,
Expand All @@ -17,7 +18,8 @@ import {
format,
getDay,
subDays,
setDay
setDay,
startOfDay
} from 'date-fns';
import { ISlimScrollOptions } from 'ngx-slimscroll';

Expand Down Expand Up @@ -51,6 +53,12 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
*/
@Input() isOpened = false;

@Input() isAlwaysOpen = false;

@Input() busyDays: Date[] = [];

@Input() events = [];

/**
* Datepicker dropdown position
*/
Expand All @@ -69,6 +77,7 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
firstCalendarDay: number;
view: string;
years: { year: number; isThisYear: boolean }[];
months: { month: string; isThisMonth: boolean }[];
dayNames: string[];
scrollOptions: ISlimScrollOptions;
days: {
Expand Down Expand Up @@ -106,18 +115,29 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
gridMargin: '0'
};
}


addBusyDay(date) {
if (this.busyDays.findIndex(busyDay => busyDay.getTime() == startOfDay(date).getTime()) == -1) {
this.busyDays.push(startOfDay(date));
}
}

ngOnInit() {
this.view = 'days';
this.date = new Date();
this.setOptions();
this.initDayNames();
this.initYears();
this.initMonths();

// Check if 'position' property is correct
if (this.positions.indexOf(this.position) === -1) {
throw new TypeError(`ng-datepicker: invalid position property value '${this.position}' (expected: ${this.positions.join(', ')})`);
}

for (let e of this.events) {
this.addBusyDay(e.visitDate);
}
}

ngOnChanges(changes: SimpleChanges) {
Expand All @@ -126,12 +146,13 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
this.initDayNames();
this.init();
this.initYears();
this.initMonths();
}
}

setOptions(): void {
const today = new Date(); // this const was added because during my tests, I noticed that at this level this.date is undefined
this.minYear = this.options && this.options.minYear || getYear(today) - 30;
this.minYear = this.options && this.options.minYear || getYear(today) - 5;
this.maxYear = this.options && this.options.maxYear || getYear(today) + 30;
this.displayFormat = this.options && this.options.displayFormat || 'MMM D[,] YYYY';
this.barTitleFormat = this.options && this.options.barTitleFormat || 'MMMM YYYY';
Expand All @@ -153,17 +174,30 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
this.date = this.days[i].date;
this.value = this.date;
this.init();
this.close();
if (!this.isAlwaysOpen)
this.close();
}

setYear(i: number): void {
this.date = setYear(this.date, this.years[i].year);
this.init();
this.initYears();
this.view = 'months';
}

setMonth(i: number): void {
this.date = setMonth(this.date, i);
this.init();
this.initMonths();
this.view = 'days';
}

init(): void {
this.busyDays = [];
for (let e of this.events) {
this.addBusyDay(e.visitDate);
}

const start = startOfMonth(this.date);
const end = endOfMonth(this.date);

Expand All @@ -175,7 +209,8 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
year: getYear(date),
inThisMonth: true,
isToday: isToday(date),
isSelected: isSameDay(date, this.innerValue) && isSameMonth(date, this.innerValue) && isSameYear(date, this.innerValue)
isSelected: isSameDay(date, this.innerValue) && isSameMonth(date, this.innerValue) && isSameYear(date, this.innerValue),
isBusy: this.busyDays.findIndex(busyDay => busyDay.getTime() == startOfDay(date).getTime()) != -1
};
});

Expand All @@ -202,6 +237,14 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
return { year: year, isThisYear: year === getYear(this.date) };
});
}

initMonths(): void {
this.months = [0,1,2,3,4,5,6,7,8,9,10,11].map(month => {
var tempDate = new Date(2010, month, 1);
var monthString = format(tempDate,'MMM');
return { month: monthString, isThisMonth: month === getMonth(this.date) };
});
}

initDayNames(): void {
this.dayNames = [];
Expand All @@ -213,11 +256,18 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
}

toggleView(): void {
this.view = this.view === 'days' ? 'years' : 'days';
if (this.view==='days') {
this.view = 'months';
} else if (this.view==='months') {
this.view = 'years';
} else if (this.view==='years') {
this.view = 'days';
}
}

toggle(): void {
this.isOpened = !this.isOpened;
if (!this.isAlwaysOpen)
this.isOpened = !this.isOpened;
}

close(): void {
Expand Down Expand Up @@ -258,7 +308,7 @@ export class NgDatepickerComponent implements ControlValueAccessor, OnInit, OnCh
}

const container = this.elementRef.nativeElement.querySelector('.ngx-datepicker-calendar-container');
if (container && container !== e.target && !container.contains(<any>e.target) && !(<any>e.target).classList.contains('year-unit')) {
if (container && container !== e.target && !container.contains(<any>e.target) && !(<any>e.target).classList.contains('year-unit') && (!this.isAlwaysOpen)) {
this.close();
}
}
Expand Down
36 changes: 12 additions & 24 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": false,
"emitDecoratorMetadata": false,
"experimentalDecorators": false,
"module": "none",
"moduleResolution": "node",
"target": "es5",
"noImplicitAny": true,
"noFallthroughCasesInSwitch": false,
"noImplicitAny": false,
"noImplicitReturns": false,
"removeComments": false,
"sourceMap": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"declaration": false,
"lib": [
"es2015",
"dom"
],
"outDir": "lib",
"typeRoots": [
"node_modules/@types"
]
},
"files": [
"index.ts"
],
"angularCompilerOptions": {
"skipMetadataEmit": true
"strictNullChecks": false,
"target": "es3"
},
"awesomeTypescriptLoaderOptions": {
"silent": true
}
}
"compileOnSave": true
}