Skip to content

Commit

Permalink
demo(datepicker): new range selection in a popup demo (#3440)
Browse files Browse the repository at this point in the history
  • Loading branch information
gpolychronis authored and maxokorokov committed Nov 5, 2019
1 parent 5610abe commit d3f44ca
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
9 changes: 9 additions & 0 deletions demo/src/app/components/datepicker/datepicker.module.ts
Expand Up @@ -29,6 +29,8 @@ import { NgbdDatepickerPopup } from './demos/popup/datepicker-popup';
import { NgbdDatepickerPopupModule } from './demos/popup/datepicker-popup.module';
import { NgbdDatepickerRange } from './demos/range/datepicker-range';
import { NgbdDatepickerRangeModule } from './demos/range/datepicker-range.module';
import { NgbdDatepickerRangePopup } from './demos/range-popup/datepicker-range-popup';
import { NgbdDatepickerRangePopupModule } from './demos/range-popup/datepicker-range-popup.module';
import { NgbdDatepickerOverviewComponent } from './overview/datepicker-overview.component';
import { NgbdDatepickerOverviewDemoComponent } from './overview/demo/datepicker-overview-demo.component';
import { NgbdDatepickerPositiontargetModule } from './demos/positiontarget/datepicker-position-target.module';
Expand Down Expand Up @@ -73,6 +75,12 @@ const DEMOS = {
code: require('!!raw-loader!./demos/range/datepicker-range').default,
markup: require('!!raw-loader!./demos/range/datepicker-range.html').default
},
rangePopup: {
title: 'Range selection in a popup',
type: NgbdDatepickerRangePopup,
code: require('!!raw-loader!./demos/range-popup/datepicker-range-popup').default,
markup: require('!!raw-loader!./demos/range-popup/datepicker-range-popup.html').default
},
disabled: {
title: 'Disabled datepicker',
type: NgbdDatepickerDisabled,
Expand Down Expand Up @@ -146,6 +154,7 @@ export const ROUTES = [
NgbdDatepickerPositiontargetModule,
NgbdDatepickerMultipleModule,
NgbdDatepickerRangeModule,
NgbdDatepickerRangePopupModule,
NgbdDatepickerAdapterModule,
...DEMO_CALENDAR_MODULES
],
Expand Down
@@ -0,0 +1,54 @@
<form class="form-inline">
<div class="form-group hidden">
<div class="input-group">
<input name="datepicker"
class="form-control"
ngbDatepicker
#datepicker="ngbDatepicker"
[autoClose]="'outside'"
(dateSelect)="onDateSelection($event)"
[displayMonths]="2"
[dayTemplate]="t"
outsideDays="hidden"
[startDate]="fromDate">
<ng-template #t let-date let-focused="focused">
<span class="custom-day"
[class.focused]="focused"
[class.range]="isRange(date)"
[class.faded]="isHovered(date) || isInside(date)"
(mouseenter)="hoveredDate = date"
(mouseleave)="hoveredDate = null">
{{ date.day }}
</span>
</ng-template>
</div>
</div>
<div class="form-group">
<div class="input-group">
<input #dpFromDate
class="form-control" placeholder="yyyy-mm-dd"
name="dpFromDate"
[value]="formatter.format(fromDate)"
(input)="fromDate = validateInput(fromDate, dpFromDate.value)">
<div class="input-group-append">
<button class="btn btn-outline-secondary calendar" (click)="datepicker.toggle()" type="button"></button>
</div>
</div>
</div>
<div class="form-group ml-2">
<div class="input-group">
<input #dpToDate
class="form-control" placeholder="yyyy-mm-dd"
name="dpToDate"
[value]="formatter.format(toDate)"
(input)="toDate = validateInput(toDate, dpToDate.value)">
<div class="input-group-append">
<button class="btn btn-outline-secondary calendar" (click)="datepicker.toggle()" type="button"></button>
</div>
</div>
</div>
</form>

<hr/>
<pre>From date model: {{ fromDate | json }}</pre>
<pre>To date model: {{ toDate | json }}</pre>
@@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

import { NgbdDatepickerRangePopup } from './datepicker-range-popup';

@NgModule({
imports: [BrowserModule, NgbModule, FormsModule],
declarations: [NgbdDatepickerRangePopup],
exports: [NgbdDatepickerRangePopup],
bootstrap: [NgbdDatepickerRangePopup]
})
export class NgbdDatepickerRangePopupModule {}
@@ -0,0 +1,72 @@
import {Component} from '@angular/core';
import {NgbDate, NgbCalendar, NgbDateParserFormatter} from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'ngbd-datepicker-range-popup',
templateUrl: './datepicker-range-popup.html',
styles: [`
.form-group.hidden {
width: 0;
margin: 0;
border: none;
padding: 0;
}
.custom-day {
text-align: center;
padding: 0.185rem 0.25rem;
display: inline-block;
height: 2rem;
width: 2rem;
}
.custom-day.focused {
background-color: #e6e6e6;
}
.custom-day.range, .custom-day:hover {
background-color: rgb(2, 117, 216);
color: white;
}
.custom-day.faded {
background-color: rgba(2, 117, 216, 0.5);
}
`]
})
export class NgbdDatepickerRangePopup {

hoveredDate: NgbDate;

fromDate: NgbDate;
toDate: NgbDate;

constructor(private calendar: NgbCalendar, public formatter: NgbDateParserFormatter) {
this.fromDate = calendar.getToday();
this.toDate = calendar.getNext(calendar.getToday(), 'd', 10);
}

onDateSelection(date: NgbDate) {
if (!this.fromDate && !this.toDate) {
this.fromDate = date;
} else if (this.fromDate && !this.toDate && date.after(this.fromDate)) {
this.toDate = date;
} else {
this.toDate = null;
this.fromDate = date;
}
}

isHovered(date: NgbDate) {
return this.fromDate && !this.toDate && this.hoveredDate && date.after(this.fromDate) && date.before(this.hoveredDate);
}

isInside(date: NgbDate) {
return date.after(this.fromDate) && date.before(this.toDate);
}

isRange(date: NgbDate) {
return date.equals(this.fromDate) || date.equals(this.toDate) || this.isInside(date) || this.isHovered(date);
}

validateInput(currentValue: NgbDate, input: string): NgbDate {
const parsed = this.formatter.parse(input);
return parsed && this.calendar.isValid(NgbDate.from(parsed)) ? NgbDate.from(parsed) : currentValue;
}
}

0 comments on commit d3f44ca

Please sign in to comment.