src/ng-xform/measure-field/measure-field.component.ts
Component to generate a bootstrap form field of numeric type
:editing: Flag to control component state :form: FormGroup containing the field :field: Intance of field configurations
ControlValueAccessor
OnInit
OnDestroy
providers |
{
: , : , : true
}
|
selector | ng-xform-measure-field |
styleUrls | measure-field.component.scss |
templateUrl | ./measure-field.component.html |
Properties |
Methods |
Accessors |
changeUnit | ||||||||||||
changeUnit(unit: string, emitEvent: )
|
||||||||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
onModelChange | ||||||||
onModelChange(value: any)
|
||||||||
Parameters :
Returns :
void
|
registerOnChange | ||||||||
registerOnChange(fn: any)
|
||||||||
Parameters :
Returns :
void
|
registerOnTouched | ||||||||
registerOnTouched(fn: any)
|
||||||||
Parameters :
Returns :
void
|
setDisabledState | ||||||||
setDisabledState(isDisabled: boolean)
|
||||||||
Parameters :
Returns :
void
|
Private setViewUnit |
setViewUnit()
|
Returns :
void
|
Private setViewUnits |
setViewUnits()
|
Returns :
void
|
Private updateInputValue |
updateInputValue()
|
Returns :
void
|
writeValue | ||||||||
writeValue(obj: Measure)
|
||||||||
Parameters :
Returns :
void
|
_onChange |
_onChange:
|
Default value : (value: any) => { }
|
_onTouched |
_onTouched:
|
Default value : () => { }
|
availableUnits |
availableUnits:
|
Type : string[]
|
inputNumber |
inputNumber:
|
Type : InputNumberComponent
|
Decorators : ViewChild
|
Private quantity |
quantity:
|
Type : Unit
|
subs |
subs:
|
Default value : new Subscription()
|
viewModel |
viewModel:
|
Type : number
|
viewUnit |
viewUnit:
|
Type : string
|
formattedValue |
getformattedValue()
|
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Unit } from 'mathjs';
import * as math from 'mathjs';
import { isObservable, Subscription } from 'rxjs';
import { BaseDynamicFieldComponent } from '../field-components/base-dynamic-field.component';
import { MeasureField } from '../fields';
import { InputNumberComponent } from '../number-field/input-number.component';
import { Measure } from './../models/measure';
/**
* Component to generate a bootstrap form field of numeric type
*
* :editing: Flag to control component state
* :form: FormGroup containing the field
* :field: Intance of field configurations
*/
@Component({
selector: 'ng-xform-measure-field',
templateUrl: './measure-field.component.html',
styleUrls: ['./measure-field.component.scss'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: MeasureFieldComponent,
multi: true
}],
})
export class MeasureFieldComponent extends BaseDynamicFieldComponent<MeasureField> implements ControlValueAccessor, OnInit, OnDestroy {
@ViewChild(InputNumberComponent) inputNumber: InputNumberComponent;
private quantity: Unit;
viewModel: number;
viewUnit: string;
availableUnits: string[];
subs = new Subscription();
_onChange = (value: any) => { };
_onTouched = () => { };
ngOnInit() {
super.ngOnInit();
this.setViewUnits();
this.setViewUnit();
}
ngOnDestroy() {
this.subs.unsubscribe();
}
get formattedValue() {
if ((this.quantity == null) || (this.viewModel == null)) {
return '-';
}
return `${this.inputNumber.toLocaleString(this.viewModel)} ${this.viewUnit}`;
}
onModelChange(value: any) {
let newValue: any;
if (value == null) {
this.quantity = null;
newValue = null;
} else {
this.quantity = math.unit(value, this.viewUnit).to(this.field.modelUnit);
newValue = new Measure(
this.quantity.toNumber(this.field.modelUnit),
this.field.modelUnit
);
}
this.updateInputValue();
this._onChange(newValue);
}
writeValue(obj: Measure): void {
if (obj != null) {
this.quantity = math.unit(obj.value, obj.unit).to(this.field.modelUnit);
} else {
this.quantity = null;
}
this.updateInputValue();
}
registerOnChange(fn: any): void {
this._onChange = fn;
}
registerOnTouched(fn: any): void {
this._onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
this.inputNumber.setDisabledState(isDisabled);
}
changeUnit(unit: string, emitEvent = true) {
this.viewUnit = !unit ? this.field.modelUnit : unit;
if (this.quantity) {
this.updateInputValue();
}
if (this.field.changedUnitHandler && emitEvent) {
this.field.changedUnitHandler(unit);
}
}
private updateInputValue() {
const newValue = this.quantity != null ? this.quantity.toNumber(this.viewUnit) : null;
if (this.viewModel !== newValue) {
this.viewModel = newValue;
}
}
private setViewUnits() {
if (!this.field.availableUnits) {
this.availableUnits = [this.field.modelUnit];
return;
}
if (isObservable(this.field.availableUnits)) {
this.field.availableUnits.subscribe(unitList => this.availableUnits = unitList);
this.availableUnits = [];
} else {
this.availableUnits = this.field.availableUnits;
}
}
private setViewUnit() {
if (!this.field.viewUnit) {
this.viewUnit = this.field.modelUnit;
return;
}
if (isObservable(this.field.viewUnit)) {
this.field.viewUnit.subscribe(unit => this.changeUnit(unit, false));
} else {
this.viewUnit = this.field.viewUnit;
}
}
}
<ng-xform-form-control-layout [fieldComponent]="instance">
<div [class.input-group]="viewUnit" [class.form-group]="!viewUnit">
<ng-xform-input-number [inputId]="elementId" [formatOptions]="field.formatOptions" [ngModel]="viewModel" (ngModelChange)="onModelChange($event)"
[inputClass]="'form-control'" [inputStyle]="{'border-top-left-radius': '4px', 'border-bottom-left-radius': '4px'}">
</ng-xform-input-number>
<div *ngIf="viewUnit" class="input-group-addon measure-unit-selector" dropdown>
<span style="cursor: pointer;" dropdownToggle>
{{viewUnit}}
<span class="caret"></span>
</span>
<ul class="dropdown-menu dropdown-menu-right" role="menu" *dropdownMenu>
<li *ngFor="let item of availableUnits">
<a href="javascript:void(0);" (click)="changeUnit(item)">{{ item }}</a>
</li>
</ul>
</div>
</div>
</ng-xform-form-control-layout>