Skip to content

Commit

Permalink
feat(datepicker): mark today's date with a custom class (#2940)
Browse files Browse the repository at this point in the history
Adds a custom CSS class `.ngb-dp-today` on a cell with today's date
and a custom `today: boolean` field in the day template context

Fixes #1470
  • Loading branch information
maxokorokov committed Feb 12, 2019
1 parent 72320b8 commit 6029304
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 9 deletions.
1 change: 1 addition & 0 deletions demo/src/app/components/datepicker/datepicker.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const OVERVIEW = {
navigation: 'Moving around',
'limiting-dates': 'Disabling and limiting dates',
'day-template': 'Day display customization',
today: 'Today\'s date',
'footer-template': 'Custom footer',
range: 'Range selection',
i18n: 'Internationalization',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,32 @@ <h4>Input date parsing and formatting</h4>



<!-- TODAY'S DATE -->
<ngbd-overview-section [section]="sections['today']">
<p>
It is often useful to highlight a today's date in the calendar view or add a certain logic to it. Today's date
is the date returned by the <a routerLink="../api" fragment="NgbCalendar">NgbCalendar</a>'s <code>getToday()</code>
method.
</p>

<p>
We add a custom CSS class <code>.ngb-dp-today</code> on a cell that corresponds to the today's date.
We do not add any rules to it at the moment, but you can add your own if necessary.
You would see something like this in the resulting markup
</p>

<ngbd-code lang="html" [code]="snippets.todayHTML"></ngbd-code>

<p>
You can also access this information from the <a routerLink="../api" fragment="DayTemplateContext">DayTemplateContext API</a>
if you're using a custom day template. It contains a <code>today: boolean</code> flag since v4.1.0
</p>

<ngbd-code lang="html" [code]="snippets.todayTemplate"></ngbd-code>

</ngbd-overview-section>


<!-- FOOTER TEMPLATE -->
<ngbd-overview-section [section]="sections['footer-template']">
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ providers: [{provide: NgbDateParserFormatter, useClass: YourOwnParserFormatter}]
{{ date.day }}
</ng-template>
<ngbDatepicker [dayTemplate]=“t”/>
`,
todayHTML: `
<div class="ngb-dp-day ngb-dp-today">
<!-- day cell content omitted -->
</div>
`,
todayTemplate: `
<ng-template #t let-today="today">
<span *ngIf="today">...</span>
</ng-template>
<ngbDatepicker [dayTemplate]=“t”/>
`,
footerTemplate: `
Expand Down
7 changes: 7 additions & 0 deletions src/datepicker/datepicker-day-template-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,11 @@ export interface DayTemplateContext {
* True if current date is selected
*/
selected: boolean;

/**
* True if current date is equal to 'NgbCalendar.getToday()'
*
* @since 4.1.0
*/
today: boolean;
}
27 changes: 19 additions & 8 deletions src/datepicker/datepicker-month-view.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,15 @@ describe('ngb-datepicker-month-view', () => {
// hidden
expect(dates[0]).toHaveCssClass('hidden');
expect(dates[0]).not.toHaveCssClass('disabled');
expect(dates[0]).not.toHaveCssClass('ngb-dp-today');
// normal
expect(dates[1]).not.toHaveCssClass('hidden');
expect(dates[1]).not.toHaveCssClass('disabled');
expect(dates[1]).not.toHaveCssClass('ngb-dp-today');
// disabled
expect(dates[2]).not.toHaveCssClass('hidden');
expect(dates[2]).toHaveCssClass('disabled');
expect(dates[2]).toHaveCssClass('ngb-dp-today');
});

it('should not display collapsed weeks', () => {
Expand Down Expand Up @@ -188,7 +191,8 @@ class TestComponent {
date: new NgbDate(2016, 7, 4),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Monday',
Expand All @@ -202,7 +206,8 @@ class TestComponent {
date: new NgbDate(2016, 8, 1),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Monday',
Expand All @@ -223,7 +228,8 @@ class TestComponent {
date: new NgbDate(2016, 8, 2),
disabled: true,
focused: false,
selected: false
selected: false,
today: true
},
tabindex: -1,
ariaLabel: 'Friday',
Expand All @@ -237,7 +243,8 @@ class TestComponent {
date: new NgbDate(2016, 8, 3),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Saturday',
Expand All @@ -258,7 +265,8 @@ class TestComponent {
date: new NgbDate(2016, 8, 4),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Sunday',
Expand All @@ -272,7 +280,8 @@ class TestComponent {
date: new NgbDate(2016, 9, 1),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Saturday',
Expand All @@ -293,7 +302,8 @@ class TestComponent {
date: new NgbDate(2016, 9, 2),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Sunday',
Expand All @@ -307,7 +317,8 @@ class TestComponent {
date: new NgbDate(2016, 9, 3),
disabled: false,
focused: false,
selected: false
selected: false,
today: false
},
tabindex: -1,
ariaLabel: 'Monday',
Expand Down
1 change: 1 addition & 0 deletions src/datepicker/datepicker-month-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {DayTemplateContext} from './datepicker-day-template-context';
[class.disabled]="day.context.disabled"
[tabindex]="day.tabindex"
[class.hidden]="day.hidden"
[class.ngb-dp-today]="day.context.today"
[attr.aria-label]="day.ariaLabel">
<ng-template [ngIf]="!day.hidden">
<ng-template [ngTemplateOutlet]="dayTemplate" [ngTemplateOutletContext]="day.context"></ng-template>
Expand Down
9 changes: 9 additions & 0 deletions src/datepicker/datepicker-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,15 @@ describe('ngb-datepicker-service', () => {
expect(getDayCtx(0).disabled).toBeFalsy();
expect(getDayCtx(1).disabled).toBeTruthy();
});

it(`should update 'today' flag for day template`, () => {
calendar.getToday = () => new NgbDate(2018, 12, 20);
const today = calendar.getToday();
service.open(today);

expect(getDay(2, 2, 0).context.today).toBeFalsy();
expect(getDay(3, 3, 0).context.today).toBeTruthy();
});
});

describe('toValidDate()', () => {
Expand Down
6 changes: 5 additions & 1 deletion src/datepicker/datepicker-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export function buildMonth(
calendar: NgbCalendar, date: NgbDate, state: DatepickerViewModel, i18n: NgbDatepickerI18n,
month: MonthViewModel = {} as MonthViewModel): MonthViewModel {
const {dayTemplateData, minDate, maxDate, firstDayOfWeek, markDisabled, outsideDays} = state;
const calendarToday = calendar.getToday();

month.firstDate = null;
month.lastDate = null;
Expand Down Expand Up @@ -155,6 +156,9 @@ export function buildMonth(
disabled = markDisabled(newDate, {month: month.number, year: month.year});
}

// today
let today = newDate.equals(calendarToday);

// adding user-provided data to the context
let contextUserData =
dayTemplateData ? dayTemplateData(newDate, {month: month.number, year: month.year}) : undefined;
Expand All @@ -180,7 +184,7 @@ export function buildMonth(
data: contextUserData,
currentMonth: month.number, disabled,
focused: false,
selected: false
selected: false, today
});
dayObject.tabindex = -1;
dayObject.ariaLabel = ariaLabel;
Expand Down

0 comments on commit 6029304

Please sign in to comment.