Skip to content

Commit

Permalink
fix(MdInput): Add a test and convert values entered based on the type…
Browse files Browse the repository at this point in the history
… of the md-input
  • Loading branch information
hansl committed Apr 18, 2016
1 parent 6cb7b9b commit e7611ce
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/components/input/input.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
[type]="type"
(focus)="onFocus()"
(blur)="onBlur()"
[(ngModel)]="value">
[(ngModel)]="value"
(change)="onChange($event)">

<label class="md-input-placeholder"
[attr.for]="id"
Expand Down
40 changes: 40 additions & 0 deletions src/components/input/input.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
describe,
it,
expect,
beforeEach,
Expand Down Expand Up @@ -215,9 +216,48 @@ export function main() {
})();
});
}));

it('supports number types and conserved its value type from Angular', injectAsync([], () => {
return builder.createAsync(MdInputNumberTypeConservedTestComponent)
.then((fixture: ComponentFixture) => {
fixture.detectChanges();

const inputEl = fixture.debugElement.query(By.css('input')).nativeElement;
inputEl.value = '3';

// Manually trigger an onchange event.
var evt = document.createEvent('HTMLEvents');
evt.initEvent('change', true, true);
inputEl.dispatchEvent(evt);

fixture.detectChanges();

// Something along the chain of events is asynchronous but does not use Zones, therefore
// we need to wait for that something to propagate. Using fakeAsync fails, just returning
// Promise.resolve(fixture) fails as well, but this passes.
return new Promise((resolve) => {
window.setTimeout(() => resolve(fixture), 0);
});
}).then((fixture: any) => {
expect(fixture.componentInstance.value).toBe(3);
expect(typeof fixture.componentInstance.value).toBe('number');
});
}));
});
}

@Component({
selector: 'test-input-controller',
template: `
<md-input type="number" [(ngModel)]="value">
</md-input>
`,
directives: [MD_INPUT_DIRECTIVES]
})
class MdInputNumberTypeConservedTestComponent {
value: number = 0;
}

@Component({
selector: 'test-input-controller',
template: `
Expand Down
19 changes: 19 additions & 0 deletions src/components/input/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export class MdInput implements ControlValueAccessor, AfterContentInit, OnChange

get value(): any { return this._value; };
@Input() set value(v: any) {
v = this._convertValueForInputType(v);
if (v !== this._value) {
this._value = v;
this._onChangeCallback(v);
Expand All @@ -163,6 +164,11 @@ export class MdInput implements ControlValueAccessor, AfterContentInit, OnChange
this._focused = false;
this._onTouchedCallback();
}
/** @internal */
onChange(ev: Event) {
this.value = (<HTMLInputElement>ev.target).value;
this._onTouchedCallback();
}

/** @internal */
hasPlaceholder(): boolean {
Expand Down Expand Up @@ -197,6 +203,19 @@ export class MdInput implements ControlValueAccessor, AfterContentInit, OnChange
this._validateConstraints();
}

/**
* Convert the value passed in to a value that is expected from the type of the md-input.
* This is normally performed by the *_VALUE_ACCESSOR in forms, but since the type is bound
* on our internal input it won't work locally.
* @private
*/
private _convertValueForInputType(v: any): any {
switch (this.type) {
case 'number': return parseFloat(v);
default: return v;
}
}

/**
* Ensure that all constraints defined by the API are validated, or throw errors otherwise.
* Constraints for now:
Expand Down

0 comments on commit e7611ce

Please sign in to comment.