Created
September 15, 2016 10:12
-
-
Save vespertilian/dd4283442622e5c36fa6f9526059a515 to your computer and use it in GitHub Desktop.
Date filter in Angular 1.2 using angular 2 style inputs (one way) and outputs (events).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let templateUrl: string = require('./date-filter.jade'); | |
require('./date-filters.sass'); | |
// note: to call the on change values you must match this call signature | |
// on-validation-change='vm.validationChange(valid)', | |
// on-date-change='vm.dateChange({toDate: toDate, fromDate: fromDate})', | |
export function dateFilter(): ng.IDirective { | |
return { | |
restrict: 'A', | |
scope: { | |
inputFromDate: '=', | |
inputToDate: '=', | |
onDateChange: '&', | |
onValidationChange: '&', | |
}, | |
templateUrl: templateUrl, | |
controller: DateFilterController, | |
controllerAs: 'vm', | |
bindToController: true, | |
}; | |
} | |
export interface IDateParams { | |
fromDate: string; | |
toDate: string; | |
} | |
export interface IValidParams { | |
valid: boolean; | |
} | |
export interface IDateFilterScope extends ng.IScope { | |
inputFromDate: any; | |
inputToDate: any; | |
onValidationChange: (validParams: IValidParams) => void; | |
onDateChange: (dateParams: IDateParams) => void; | |
} | |
export class DateFilterController { | |
public toDateModel: Date; | |
public fromDateModel: Date; | |
public today: Date; | |
public dateOptions: any; | |
public format: string; | |
public toDateOpen: boolean; | |
public fromDateOpen: boolean; | |
public fromDateGreaterThanToDate: boolean; | |
public toDateInFuture: boolean; | |
public periodGreaterThanOneMonth: boolean; | |
// ie8 being used in view | |
/*@ngInject*/ | |
constructor( | |
private moment: any, | |
private $scope: IDateFilterScope, | |
public ie8: boolean | |
) { | |
this.format = 'dd/MM/yy'; | |
this.today = new Date(); | |
this.dateOptions = { | |
formatYear: 'yy', | |
startingDay: 1, | |
}; | |
// by copying the value we create a one way binding | |
$scope.$watch('inputFromDate', (newValue: string) => { | |
if (newValue) { | |
this.fromDateModel = angular.copy(moment(newValue, 'YYYYMMDD')._d); | |
this.validate(); | |
} | |
}); | |
// by copying the value we create a one way binding | |
$scope.$watch('inputToDate', (newValue: string) => { | |
if (newValue) { | |
this.toDateModel = angular.copy(moment(newValue, 'YYYYMMDD')._d); | |
this.validate(); | |
} | |
}); | |
} | |
public open($event: ng.IAngularEvent, openDatePicker: string): void { | |
$event.preventDefault(); | |
$event.stopPropagation(); | |
this[openDatePicker] = true; | |
} | |
public dateChanged(): void { | |
// called via ng-change | |
let toDateString: string = this.moment(this.toDateModel).format('YYYYMMDD'); | |
let fromDateString: string = this.moment(this.fromDateModel).format('YYYYMMDD'); | |
if (this.$scope.onDateChange) { | |
this.$scope.onDateChange({fromDate: fromDateString, toDate: toDateString}); | |
} | |
this.validate(); | |
} | |
private validate(): void { | |
let fromDate: any = this.moment(this.fromDateModel); | |
let toDate: any = this.moment(this.toDateModel); | |
let now: any = this.moment(); | |
this.fromDateGreaterThanToDate = fromDate.diff(toDate) > 0; | |
this.toDateInFuture = toDate.diff(now) > 0; | |
this.periodGreaterThanOneMonth = toDate.diff(fromDate, 'months', true) > 1; | |
let valid: boolean = !this.fromDateGreaterThanToDate && !this.toDateInFuture && !this.periodGreaterThanOneMonth; | |
if (this.$scope.onValidationChange) { | |
this.$scope.onValidationChange({valid: valid}); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.row | |
.col-md-12 | |
div(ng-click='vm.toggleCalendar()') | |
form.row(ng-submit='vm.changeDate()') | |
label.col-md-12 | |
| Date range | |
.field.col-md-6 | |
input#plainFromDateInput( | |
ng-if='vm.ie8', | |
ng-model='vm.fromDateModel', | |
date-input-formatter, | |
ng-change='vm.dateChanged()' | |
) | |
p.input-group(ng-if='!vm.ie8') | |
input.form-control.date-filter-from-date(type='text', datepicker-popup='{{vm.format}}', ng-model='vm.fromDateModel', is-open='vm.fromDateOpen', max-date='vm.today', datepicker-options='vm.dateOptions', ng-required='true', close-text='Close', ng-change='vm.dateChanged()') | |
span.input-group-btn | |
button.btn.btn-default.date-filter-button(type='button', ng-click="vm.open($event, 'fromDateOpen')") | |
i.glyphicon.glyphicon-calendar | |
span.date-range-text | |
| to | |
.field.col-md-6 | |
input#plainToDateInput( | |
ng-if='vm.ie8', | |
ng-model='vm.toDateModel', | |
date-input-formatter, | |
ng-change='vm.dateChanged()' | |
) | |
p.input-group(ng-if='!vm.ie8') | |
input.form-control.date-filter-to-date(type='text', datepicker-popup='{{vm.format}}', ng-model='vm.toDateModel', is-open='vm.toDateOpen', max-date='vm.today', datepicker-options='vm.dateOptions', ng-required='true', close-text='Close', ng-change='vm.dateChanged()') | |
span.input-group-btn | |
button.btn.btn-default.date-filter-button(type='button', ng-click="vm.open($event, 'toDateOpen')") | |
i.glyphicon.glyphicon-calendar | |
.alert.alert-warning(ng-if='vm.toDateInFuture') | |
| To date cannot be in the future. | |
.alert.alert-warning(ng-if='vm.fromDateGreaterThanToDate') | |
| The from date should be before the to date. | |
.alert.alert-warning(ng-if='vm.periodGreaterThanOneMonth') | |
| The date range period must be one month or less. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment