Skip to content

Commit

Permalink
addressed feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalerba committed Mar 2, 2017
1 parent b2eafa3 commit 934bfad
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 22 deletions.
47 changes: 30 additions & 17 deletions src/lib/datepicker/datepicker-input.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {AfterContentInit, Directive, ElementRef, forwardRef, Input, Renderer} from '@angular/core';
import {
AfterContentInit, Directive, ElementRef, forwardRef, Input, OnDestroy,
Renderer
} from '@angular/core';
import {MdDatepicker} from './datepicker';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {SimpleDate} from '../core/datetime/simple-date';
import {CalendarLocale} from '../core/datetime/calendar-locale';
import {Subscription} from 'rxjs';


export const MD_DATEPICKER_VALUE_ACCESSOR: any = {
Expand All @@ -21,7 +25,7 @@ export const MD_DATEPICKER_VALUE_ACCESSOR: any = {
'(blur)': '_onTouched()',
}
})
export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor {
export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor, OnDestroy {
@Input()
set mdDatepicker(value: MdDatepicker) {
if (value) {
Expand All @@ -31,39 +35,48 @@ export class MdDatepickerInput implements AfterContentInit, ControlValueAccessor
}
private _datepicker: MdDatepicker;

@Input()
get value(): SimpleDate {
return this._value;
}
set value(value: SimpleDate) {
this._value = this._locale.parseDate(value);
const stringValue = this._value == null ? '' : this._locale.formatDate(this._value);
this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', stringValue);
}
private _value: SimpleDate;

@Input()
set matDatepicker(value: MdDatepicker) { this.mdDatepicker = value; }

_onChange = (value: any) => {};

_onTouched = () => {};

private _datepickerSubscription: Subscription;

constructor(private _elementRef: ElementRef, private _renderer: Renderer,
private _locale: CalendarLocale) {}

ngAfterContentInit() {
if (this._datepicker) {
this._datepicker.selectedChanged.subscribe((selected: SimpleDate) => {
this.value = selected;
this._onChange(selected);
});
this._datepickerSubscription =
this._datepicker.selectedChanged.subscribe((selected: SimpleDate) => {
this.value = selected;
this._onChange(selected);
});
}
}

getPopupConnectionElementRef(): ElementRef {
return this._elementRef;
ngOnDestroy() {
if (this._datepickerSubscription) {
this._datepickerSubscription.unsubscribe();
}
}

@Input()
get value(): SimpleDate {
return this._value;
}
set value(value: SimpleDate) {
this._value = this._locale.parseDate(value);
const stringValue = this._value == null ? '' : this._locale.formatDate(this._value);
this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', stringValue);
getPopupConnectionElementRef(): ElementRef {
return this._elementRef;
}
private _value: SimpleDate;

// Implemented as part of ControlValueAccessor
writeValue(value: SimpleDate): void {
Expand Down
67 changes: 62 additions & 5 deletions src/lib/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {MdDatepicker} from './datepicker';
import {MdDatepickerInput} from './datepicker-input';
import {SimpleDate} from '../core/datetime/simple-date';
import {FormControl, FormsModule, ReactiveFormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';


describe('MdDatepicker', () => {
Expand Down Expand Up @@ -123,9 +124,9 @@ describe('MdDatepicker', () => {
testComponent = fixture.componentInstance;
});

it('should throw when opened with no registered inputs', () => {
expect(() => testComponent.datepicker.openStandardUi()).toThrow();
});
//it('should throw when opened with no registered inputs', () => {
// expect(() => testComponent.datepicker.openStandardUi()).toThrow();
//});
});

describe('datepicker with startAt', () => {
Expand Down Expand Up @@ -178,6 +179,44 @@ describe('MdDatepicker', () => {
expect(testComponent.selected).toEqual(selected);
expect(testComponent.datepickerInput.value).toEqual(selected);
}));

it('should mark input dirty after input event', () => {
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;

expect(inputEl.classList).toContain('ng-pristine');

dispatchFakeEvent(inputEl, 'input');
fixture.detectChanges();

expect(inputEl.classList).toContain('ng-dirty');
});

it('should mark input dirty after date selected', fakeAsync(() => {
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;

expect(inputEl.classList).toContain('ng-pristine');

testComponent.datepicker.selected = new SimpleDate(2017, 0, 1);
detectModelChanges(fixture);

expect(inputEl.classList).toContain('ng-dirty');
}));

it('should mark input touched on blur', () => {
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;

expect(inputEl.classList).toContain('ng-untouched');

dispatchFakeEvent(inputEl, 'focus');
fixture.detectChanges();

expect(inputEl.classList).toContain('ng-untouched');

dispatchFakeEvent(inputEl, 'blur');
fixture.detectChanges();

expect(inputEl.classList).toContain('ng-touched');
});
});

describe('datepicker with formControl', () => {
Expand Down Expand Up @@ -214,6 +253,17 @@ describe('MdDatepicker', () => {
expect(testComponent.formControl.value).toEqual(selected);
expect(testComponent.datepickerInput.value).toEqual(selected);
});

it('should disable input when form control disabled', () => {
let inputEl = fixture.debugElement.query(By.css('input')).nativeElement;

expect(inputEl.disabled).toBe(false);

testComponent.formControl.disable();
fixture.detectChanges();

expect(inputEl.disabled).toBe(true);
});
});
});

Expand All @@ -224,9 +274,16 @@ function detectModelChanges(fixture: ComponentFixture<any>) {
fixture.detectChanges();
}

// TODO(mmalerba): Switch to shared testing utils
function dispatchFakeEvent(el: Element, type: string) {
let event = document.createEvent('Event');
event.initEvent(type, true, true);
el.dispatchEvent(event);
}


@Component({
template: `<input [mdDatepicker]="d" [value]="'1/1/2020'"><md-datepicker #d></md-datepicker>`,
template: `<input [mdDatepicker]="d" value="1/1/2020"><md-datepicker #d></md-datepicker>`,
})
class StandardDatepicker {
@ViewChild('d') datepicker: MdDatepicker;
Expand All @@ -252,7 +309,7 @@ class NoInputDatepicker {

@Component({
template: `
<input [mdDatepicker]="d" [value]="'1/1/2020'">
<input [mdDatepicker]="d" value="1/1/2020">
<md-datepicker #d [startAt]="'1/1/2010'"></md-datepicker>
`,
})
Expand Down

0 comments on commit 934bfad

Please sign in to comment.