From ad239218140989ca28d26dc58ef4f7737a25e3d6 Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Thu, 7 May 2015 09:10:41 -0700 Subject: [PATCH] feat(material): early version of md-input Closes #1753 --- .../src/components/input/input.js | 117 +++++++++++++++++- .../examples/src/material/input/demo_app.html | 37 +++++- .../examples/src/material/input/index.html | 5 +- modules/examples/src/material/input/index.js | 10 +- 4 files changed, 152 insertions(+), 17 deletions(-) diff --git a/modules/angular2_material/src/components/input/input.js b/modules/angular2_material/src/components/input/input.js index 652ede3cb1..ce0c534ad4 100644 --- a/modules/angular2_material/src/components/input/input.js +++ b/modules/angular2_material/src/components/input/input.js @@ -1,17 +1,126 @@ -import {Directive} from 'angular2/src/core/annotations_impl/annotations'; +import {Directive, onAllChangesDone} from 'angular2/src/core/annotations_impl/annotations'; +import {Attribute} from 'angular2/src/core/annotations_impl/di'; +import {Parent} from 'angular2/src/core/annotations_impl/visibility'; + +import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async'; + +// TODO(jelbourn): validation (will depend on Forms API). +// TODO(jelbourn): textarea resizing +// TODO(jelbourn): max-length counter +// TODO(jelbourn): placeholder property @Directive({ - selector: 'md-input-container input' + selector: 'md-input-container input', + events: ['mdChange', 'mdFocusChange'], + hostProperties: { + 'yes': 'class.md-input' + }, + hostListeners: { + 'input': 'updateValue($event)', + 'focus': 'setHasFocus(true)', + 'blur': 'setHasFocus(false)' + } }) export class MdInput { - constructor() { + value: string; + yes: boolean; + // Events emitted by this directive. We use these special 'md-' events to communicate + // to the parent MdInputContainer. + mdChange: EventEmitter; + mdFocusChange: EventEmitter; + + constructor( + @Attribute('value') value: String, + @Parent() container: MdInputContainer) { + // TODO(jelbourn): Remove this when #1402 is done. + this.yes = true; + + this.value = value == null ? '' : value; + this.mdChange = new EventEmitter(); + this.mdFocusChange = new EventEmitter(); + + container.registerInput(this); + } + + updateValue(event) { + this.value = event.target.value; + ObservableWrapper.callNext(this.mdChange, this.value); + } + + setHasFocus(hasFocus: boolean) { + ObservableWrapper.callNext(this.mdFocusChange, hasFocus); } } +@Directive({ + selector: 'md-input-container textarea', + events: ['mdChange', 'mdFocusChange'], + hostProperties: { + 'yes': 'class.md-input' + }, + hostListeners: { + 'input': 'updateValue($event)', + 'focus': 'setHasFocus(true)', + 'blur': 'setHasFocus(false)' + } +}) +export class MdTextarea extends MdInput { + constructor( + @Attribute('value') value: String, + @Parent() container: MdInputContainer) { + super(value, container); + } +} @Directive({ - selector: 'md-input-container' + selector: 'md-input-container', + lifecycle: [onAllChangesDone], + hostProperties: { + 'inputHasValue': 'class.md-input-has-value', + 'inputHasFocus': 'class.md-input-focused' + } }) export class MdInputContainer { + // The MdInput or MdTextarea inside of this container. + _input: MdInput; + + // Whether the input inside of this container has a non-empty value. + inputHasValue: boolean; + + // Whether the input inside of this container has focus. + inputHasFocus: boolean; + + constructor() { + this._input = null; + this.inputHasValue = false; + this.inputHasFocus = false; + } + + onAllChangesDone() { + // Enforce that this directive actually contains a text input. + if (this._input == null) { + throw 'No or diff --git a/modules/examples/src/material/input/index.html b/modules/examples/src/material/input/index.html index 7a5e92d1a3..548b5126bb 100644 --- a/modules/examples/src/material/input/index.html +++ b/modules/examples/src/material/input/index.html @@ -4,12 +4,11 @@ ng-material input demo - + - Loading... - $SCRIPTS$ diff --git a/modules/examples/src/material/input/index.js b/modules/examples/src/material/input/index.js index 529dcca63c..e97973b370 100644 --- a/modules/examples/src/material/input/index.js +++ b/modules/examples/src/material/input/index.js @@ -1,5 +1,5 @@ import {bootstrap} from 'angular2/angular2'; -import {MdCheckbox} from 'angular2_material/src/components/checkbox/checkbox' +import {MdInputContainer, MdInput, MdTextarea} from 'angular2_material/src/components/input/input' import {UrlResolver} from 'angular2/src/services/url_resolver'; import {commonDemoSetup, DemoUrlResolver} from '../demo_common'; import {bind} from 'angular2/di'; @@ -14,17 +14,11 @@ import {View} from 'angular2/src/core/annotations_impl/view'; }) @View({ templateUrl: './demo_app.html', - directives: [MdCheckbox] + directives: [MdInputContainer, MdInput, MdTextarea] }) class DemoApp { - toggleCount: number; - constructor() { - this.toggleCount = 0; - } - increment() { - this.toggleCount++; } }