Angular 2+ 货币掩码
Angular 2+ Currency Mask
我尝试了一些 Angular 2+ 的货币掩码,但我的要求并不真正适合它们,所以我正在尝试自己创建一个指令。这是我需要的:
- 允许空值。将值保留为数字,而不是字符串。
- On Focus 移除货币格式。关于模糊重新格式化。
- 从右到左输入数字(因此对于 250.00 美元,用户必须键入 [2] -> 5 -> 0。(因此不是从小数点开始)
- 不允许用户输入除数字和小数点分隔符以外的任何内容。
- 文本右对齐
我完成了大部分工作。
唯一的问题是它只适用于 focus/blur/keypress。由于我的组件的数据是异步加载的,指令中没有事件被触发,因此现有美元金额的初始加载没有格式化。到目前为止,这是我的指令:
import { Directive, ElementRef, HostListener, Input, AfterViewInit } from '@angular/core';
import { CurrencyMaskService } from './currency-mask.service';
@Directive({
selector: '[appCurrencyMask]'
})
export class CurrencyMaskDirective implements AfterViewInit {
private el: HTMLInputElement;
constructor(private elementRef: ElementRef, private currencyMaskService: CurrencyMaskService) {
this.el = elementRef.nativeElement;
}
ngAfterViewInit() {
this.el.style.textAlign = 'right';
}
// On Focus remove all non-digit or decimal separator values
@HostListener('focus', ['$event.target.value'])
onfocus(value) {
this.el.value = this.currencyMaskService.parse(value);
}
// On Blur remove all symbols except last . and set to currency format
@HostListener('blur', ['$event.target.value'])
onBlur(value) {
this.el.value = this.currencyMaskService.transform(value);
}
// On Blur remove all symbols except last . and set to currency format
@HostListener('change', ['$event.target.value'])
onChange(value) {
this.el.value = this.currencyMaskService.transform(value);
}
// Prevent user to enter anything but digits and decimal separator
@HostListener('keypress', ['$event'])
onKeyPress(event) {
const key = event.which || event.keyCode || 0;
if (key !== 46 && key > 31 && (key < 48 || key > 57)) {
event.preventDefault();
}
}
}
Reddit r/Angular2 社区能够帮助我找到答案:https://www.reddit.com/r/Angular2/comments/82oojo/angular_2_currency_mask/
我完全不知道如何跟踪值本身,通过使用 ControlValueAccessor 我能够完成我想要的。请参阅下面的代码:
import { Directive, ElementRef, HostListener, AfterViewInit, Input, forwardRef } from '@angular/core';
import { CurrencyMaskService } from './currency-mask.service';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
const noop = () => {};
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CurrencyMaskDirective),
multi: true
};
@Directive({
selector: '[appCurrencyMask]',
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CurrencyMaskDirective implements AfterViewInit, ControlValueAccessor {
private el: HTMLInputElement;
private innerValue: any = 0;
constructor(private elementRef: ElementRef, private currencyMaskService: CurrencyMaskService) {
this.el = elementRef.nativeElement;
}
// Placeholders for the callbacks which are later providesd
// by the Control Value Accessor
private onTouchedCallback: () => void = noop;
private onChangeCallback: (a: any) => void = noop;
// set getter
get value(): any {
return this.innerValue;
}
// set accessor including call the onchange callback
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
// Set touched on blur
// onBlur() {
// this.onTouchedCallback();
// }
// From ControlValueAccessor interface
writeValue(value: any) {
if (value !== this.innerValue) {
this.el.value = this.currencyMaskService.transform(value);
this.innerValue = value;
}
}
// From ControlValueAccessor interface
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
// From ControlValueAccessor interface
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
ngAfterViewInit() {
this.el.style.textAlign = 'right';
}
// On Focus remove all non-digit or decimal separator values
@HostListener('focus', ['$event.target.value'])
onfocus(value) {
this.el.value = this.currencyMaskService.parse(value);
}
// On Blue remove all symbols except last . and set to currency format
@HostListener('blur', ['$event.target.value'])
onBlur(value) {
this.onTouchedCallback();
this.el.value = this.currencyMaskService.transform(value);
this.onChangeCallback(this.currencyMaskService.parse(this.el.value));
}
// On Change remove all symbols except last . and set to currency format
@HostListener('change', ['$event.target.value'])
onChange(value) {
this.el.value = this.currencyMaskService.transform(value);
this.onChangeCallback(this.currencyMaskService.parse(this.el.value));
}
// Prevent user to enter anything but digits and decimal separator
@HostListener('keypress', ['$event'])
onKeyPress(event) {
const key = event.which || event.keyCode || 0;
if (key !== 46 && key > 31 && (key < 48 || key > 57)) {
event.preventDefault();
}
}
}
*编辑:
这是我最终使用的完整代码:https://github.com/LeoTanoue/ngx-currency-mask
我尝试了一些 Angular 2+ 的货币掩码,但我的要求并不真正适合它们,所以我正在尝试自己创建一个指令。这是我需要的:
- 允许空值。将值保留为数字,而不是字符串。
- On Focus 移除货币格式。关于模糊重新格式化。
- 从右到左输入数字(因此对于 250.00 美元,用户必须键入 [2] -> 5 -> 0。(因此不是从小数点开始)
- 不允许用户输入除数字和小数点分隔符以外的任何内容。
- 文本右对齐
我完成了大部分工作。
唯一的问题是它只适用于 focus/blur/keypress。由于我的组件的数据是异步加载的,指令中没有事件被触发,因此现有美元金额的初始加载没有格式化。到目前为止,这是我的指令:
import { Directive, ElementRef, HostListener, Input, AfterViewInit } from '@angular/core';
import { CurrencyMaskService } from './currency-mask.service';
@Directive({
selector: '[appCurrencyMask]'
})
export class CurrencyMaskDirective implements AfterViewInit {
private el: HTMLInputElement;
constructor(private elementRef: ElementRef, private currencyMaskService: CurrencyMaskService) {
this.el = elementRef.nativeElement;
}
ngAfterViewInit() {
this.el.style.textAlign = 'right';
}
// On Focus remove all non-digit or decimal separator values
@HostListener('focus', ['$event.target.value'])
onfocus(value) {
this.el.value = this.currencyMaskService.parse(value);
}
// On Blur remove all symbols except last . and set to currency format
@HostListener('blur', ['$event.target.value'])
onBlur(value) {
this.el.value = this.currencyMaskService.transform(value);
}
// On Blur remove all symbols except last . and set to currency format
@HostListener('change', ['$event.target.value'])
onChange(value) {
this.el.value = this.currencyMaskService.transform(value);
}
// Prevent user to enter anything but digits and decimal separator
@HostListener('keypress', ['$event'])
onKeyPress(event) {
const key = event.which || event.keyCode || 0;
if (key !== 46 && key > 31 && (key < 48 || key > 57)) {
event.preventDefault();
}
}
}
Reddit r/Angular2 社区能够帮助我找到答案:https://www.reddit.com/r/Angular2/comments/82oojo/angular_2_currency_mask/
我完全不知道如何跟踪值本身,通过使用 ControlValueAccessor 我能够完成我想要的。请参阅下面的代码:
import { Directive, ElementRef, HostListener, AfterViewInit, Input, forwardRef } from '@angular/core';
import { CurrencyMaskService } from './currency-mask.service';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
const noop = () => {};
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CurrencyMaskDirective),
multi: true
};
@Directive({
selector: '[appCurrencyMask]',
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CurrencyMaskDirective implements AfterViewInit, ControlValueAccessor {
private el: HTMLInputElement;
private innerValue: any = 0;
constructor(private elementRef: ElementRef, private currencyMaskService: CurrencyMaskService) {
this.el = elementRef.nativeElement;
}
// Placeholders for the callbacks which are later providesd
// by the Control Value Accessor
private onTouchedCallback: () => void = noop;
private onChangeCallback: (a: any) => void = noop;
// set getter
get value(): any {
return this.innerValue;
}
// set accessor including call the onchange callback
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
// Set touched on blur
// onBlur() {
// this.onTouchedCallback();
// }
// From ControlValueAccessor interface
writeValue(value: any) {
if (value !== this.innerValue) {
this.el.value = this.currencyMaskService.transform(value);
this.innerValue = value;
}
}
// From ControlValueAccessor interface
registerOnChange(fn: any) {
this.onChangeCallback = fn;
}
// From ControlValueAccessor interface
registerOnTouched(fn: any) {
this.onTouchedCallback = fn;
}
ngAfterViewInit() {
this.el.style.textAlign = 'right';
}
// On Focus remove all non-digit or decimal separator values
@HostListener('focus', ['$event.target.value'])
onfocus(value) {
this.el.value = this.currencyMaskService.parse(value);
}
// On Blue remove all symbols except last . and set to currency format
@HostListener('blur', ['$event.target.value'])
onBlur(value) {
this.onTouchedCallback();
this.el.value = this.currencyMaskService.transform(value);
this.onChangeCallback(this.currencyMaskService.parse(this.el.value));
}
// On Change remove all symbols except last . and set to currency format
@HostListener('change', ['$event.target.value'])
onChange(value) {
this.el.value = this.currencyMaskService.transform(value);
this.onChangeCallback(this.currencyMaskService.parse(this.el.value));
}
// Prevent user to enter anything but digits and decimal separator
@HostListener('keypress', ['$event'])
onKeyPress(event) {
const key = event.which || event.keyCode || 0;
if (key !== 46 && key > 31 && (key < 48 || key > 57)) {
event.preventDefault();
}
}
}
*编辑: 这是我最终使用的完整代码:https://github.com/LeoTanoue/ngx-currency-mask