179 lines
4.3 KiB
JavaScript
Raw Normal View History

import {View, Component, Decorator, Ancestor, onChange, PropertySetter} from 'angular2/angular2';
import {Optional} from 'angular2/di';
import {isBlank, isPresent, isString, CONST} from 'angular2/src/facade/lang';
2015-02-07 14:14:07 -08:00
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {ControlGroup, Control} from './model';
import {Validators} from './validators';
//export interface ControlValueAccessor {
// writeValue(value):void{}
// set onChange(fn){}
//}
2015-02-07 14:14:07 -08:00
/**
* @exportedAs angular2/forms
*/
@Decorator({
selector: '[control]',
hostListeners: {
'change' : 'onChange($event.target.value)',
'input' : 'onChange($event.target.value)'
2015-02-07 14:14:07 -08:00
}
})
export class DefaultValueAccessor {
_setValueProperty:Function;
onChange:Function;
2015-02-07 14:14:07 -08:00
constructor(@PropertySetter('value') setValueProperty:Function) {
this._setValueProperty = setValueProperty;
this.onChange = (_) => {};
2015-02-07 14:14:07 -08:00
}
writeValue(value) {
this._setValueProperty(value);
2015-02-07 14:14:07 -08:00
}
}
/**
* @exportedAs angular2/forms
*/
@Decorator({
2015-03-30 20:52:37 -07:00
selector: 'input[type=checkbox][control]',
hostListeners: {
'change' : 'onChange($event.target.checked)'
2015-02-07 14:14:07 -08:00
}
})
export class CheckboxControlValueAccessor {
_setCheckedProperty:Function;
onChange:Function;
2015-02-07 14:14:07 -08:00
constructor(cd:ControlDirective, @PropertySetter('checked') setCheckedProperty:Function) {
this._setCheckedProperty = setCheckedProperty;
this.onChange = (_) => {};
cd.valueAccessor = this; //ControlDirective should inject CheckboxControlDirective
2015-02-07 14:14:07 -08:00
}
writeValue(value) {
this._setCheckedProperty(value);
2015-02-07 14:14:07 -08:00
}
}
/**
* @exportedAs angular2/forms
*/
@Decorator({
lifecycle: [onChange],
selector: '[control]',
properties: {
'controlOrName' : 'control'
}
})
export class ControlDirective {
_groupDirective:ControlGroupDirective;
2015-02-07 14:14:07 -08:00
controlOrName:any;
valueAccessor:any; //ControlValueAccessor
validator:Function;
constructor(@Optional() @Ancestor() groupDirective:ControlGroupDirective, valueAccessor:DefaultValueAccessor) {
this._groupDirective = groupDirective;
this.controlOrName = null;
this.valueAccessor = valueAccessor;
this.validator = Validators.nullValidator;
}
// TODO: vsavkin this should be moved into the constructor once static bindings
// are implemented
onChange(_) {
this._initialize();
}
2015-02-07 14:14:07 -08:00
_initialize() {
if(isPresent(this._groupDirective)) {
this._groupDirective.addDirective(this);
}
2015-02-24 11:59:10 -08:00
var c = this._control();
c.validator = Validators.compose([c.validator, this.validator]);
2015-02-07 14:14:07 -08:00
this._updateDomValue();
this._setUpUpdateControlValue();
}
2015-02-07 14:14:07 -08:00
_updateDomValue() {
this.valueAccessor.writeValue(this._control().value);
}
_setUpUpdateControlValue() {
this.valueAccessor.onChange = (newValue) => this._control().updateValue(newValue);
}
_control() {
if (isString(this.controlOrName)) {
return this._groupDirective.findControl(this.controlOrName);
} else {
return this.controlOrName;
}
}
}
/**
* @exportedAs angular2/forms
*/
@Decorator({
selector: '[control-group]',
properties: {
'controlGroup' : 'control-group'
}
})
export class ControlGroupDirective {
_groupDirective:ControlGroupDirective;
_controlGroupName:string;
_controlGroup:ControlGroup;
_directives:List<ControlDirective>;
constructor(@Optional() @Ancestor() groupDirective:ControlGroupDirective) {
this._groupDirective = groupDirective;
this._directives = ListWrapper.create();
}
set controlGroup(controlGroup) {
if (isString(controlGroup)) {
this._controlGroupName = controlGroup;
} else {
this._controlGroup = controlGroup;
}
this._updateDomValue();
}
_updateDomValue() {
2015-02-07 14:14:07 -08:00
ListWrapper.forEach(this._directives, (cd) => cd._updateDomValue());
}
addDirective(c:ControlDirective) {
ListWrapper.push(this._directives, c);
}
findControl(name:string):any {
return this._getControlGroup().controls[name];
}
_getControlGroup():ControlGroup {
if (isPresent(this._controlGroupName)) {
return this._groupDirective.findControl(this._controlGroupName)
} else {
return this._controlGroup;
}
}
}
2015-02-07 14:14:07 -08:00
/**
* @exportedAs angular2/forms
*/
// todo(misko): rename to lover case as it is not a Type but a var.
2015-02-07 14:14:07 -08:00
export var FormDirectives = [
ControlGroupDirective, ControlDirective, CheckboxControlValueAccessor, DefaultValueAccessor
2015-02-07 14:14:07 -08:00
];