2017-01-23 93 views

回答

3

我使用该解决方案的JavaScript代码@管

import { Directive,Input,Inject, HostListener, ElementRef, OnInit } from "@angular/core"; 


const PADDING = "000000"; 

@Pipe({ name: "CurrencyPipe" }) 
export class CurrencyPipe implements PipeTransform { 
    transform(value: any, args: string[]): any { 
    var clean = value.replace(/[^-0-9\.]/g, ''); 
    var negativeCheck = clean.split('-'); 
    var decimalCheck = clean.split('.'); 

    if (negativeCheck[1] != undefined) { 
         negativeCheck[1] = negativeCheck[1].slice(0, negativeCheck[1].length); 
         clean = negativeCheck[0] + '-' + negativeCheck[1]; 
         if (negativeCheck[0].length > 0) { 
          clean = negativeCheck[0]; 
         } 

        } 
     if (decimalCheck[1] != undefined) { 
         decimalCheck[1] = decimalCheck[1].slice(0, 2); 
         clean = decimalCheck[0] + '.' + decimalCheck[1]; 
        } 

    return clean; 
    } 

    parse(value: string, fractionSize: number = 2): string { 

    var clean = value.replace(/[^-0-9\.]/g, ''); 
    var negativeCheck = clean.split('-'); 
    var decimalCheck = clean.split('.'); 

    if (negativeCheck[1] != undefined) { 
         negativeCheck[1] = negativeCheck[1].slice(0, negativeCheck[1].length); 
         clean = negativeCheck[0] + '-' + negativeCheck[1]; 
         if (negativeCheck[0].length > 0) { 
          clean = negativeCheck[0]; 
         } 

        } 
     if (decimalCheck[1] != undefined) { 
         decimalCheck[1] = decimalCheck[1].slice(0, 2); 
         clean = decimalCheck[0] + '.' + decimalCheck[1]; 
        } 

    return clean; 
    } 

} 

和管延伸我的指令。您的组件

import { CurrencyFormatterDirective } from '../../shared/directive/showOnRowHover'; 
import { CurrencyPipe } from '../../shared/pipe/orderby'; 
providers: [CurrencyPipe, 
      CurrencyFormatterDirective] 

和指导你的HTML输入

<input type="text" [(ngModel)]="invoiceDetail.InvoiceAmount" class="form-control" placeholder="Enter invoice amount" 
      CurrencyFormatter> 
+1

这很好,但我必须从核心导入PipeTransform,并将该管道作为提供程序添加到指令中,以便将其注入,并将其添加到模块的声明中 – user917170

-1
<input type='number' step='0.01' value='0.00' placeholder='0.00' /> 

不使用Step使用step,如果你还是想旧浏览器的支持,你可以选择为同一

+3

不限制用户输入2位以上的小数。 –

1

以下指令在Plnkr的见演示上

import { Directive, Input, Inject, HostListener, OnChanges, ElementRef, Renderer, AfterViewInit, OnInit } from "@angular/core"; 
import { CurrencyPipe } from '../../shared/pipe/orderby'; 

@Directive({ selector: "[CurrencyFormatter]" }) 
export class CurrencyFormatterDirective { 

    private el: HTMLInputElement; 

    constructor(
    private elementRef: ElementRef, 
    private currencyPipe: CurrencyPipe 
) { 
    this.el = this.elementRef.nativeElement; 
    } 

    ngOnInit() { 
    this.el.value = this.currencyPipe.parse(this.el.value); 
    } 

    @HostListener("focus", ["$event.target.value"]) 
    onFocus(value) { 
    this.el.value = this.currencyPipe.parse(value); // opossite of transform 
    } 

    @HostListener("blur", ["$event.target.value"]) 
    onBlur(value) { 
    this.el.value = this.currencyPipe.parse(value); 
    } 

    @HostListener("keyup", ["$event.target.value"]) 
    onKeyUp(value) { 
    this.el.value = this.currencyPipe.parse(value); 
    } 



} 

导入指令。

您可以使用下面的指令实现这一点:

import { Directive, ElementRef, HostListener, Input } from '@angular/core'; 

@Directive({ 
    selector: '[OnlyNumber]' 
}) 
export class OnlyNumber { 
    elemRef: ElementRef 

    constructor(private el: ElementRef) { 
    this.elemRef = el 
    } 

    @Input() OnlyNumber: boolean; 
    @Input() DecimalPlaces: string; 
    @Input() minValue: string; 
    @Input() maxValue: string; 

    @HostListener('keydown', ['$event']) onKeyDown(event) { 
    let e = <KeyboardEvent> event; 
    if (this.OnlyNumber) { 
     if ([46, 8, 9, 27, 13, 110, 190].indexOf(e.keyCode) !== -1 || 
     // Allow: Ctrl+A 
     (e.keyCode == 65 && e.ctrlKey === true) || 
     // Allow: Ctrl+C 
     (e.keyCode == 67 && e.ctrlKey === true) || 
     // Allow: Ctrl+X 
     (e.keyCode == 88 && e.ctrlKey === true) || 
     // Allow: home, end, left, right 
     (e.keyCode >= 35 && e.keyCode <= 39)) { 
      // let it happen, don't do anything 
      return; 
     } 
     // Ensure that it is a number and stop the keypress 
     if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) { 
      e.preventDefault(); 
     } 
     } 
    } 

    @HostListener('keypress', ['$event']) onKeyPress(event) { 
    let e = <any> event 

    let valInFloat: number = parseFloat(e.target.value) 

    if(this.minValue.length) { 
     // (isNaN(valInFloat) && e.key === "0") - When user enters value for first time valInFloat will be NaN, e.key condition is 
     // because I didn't want user to enter anything below 1. 
     // NOTE: You might want to remove it if you want to accept 0 
     if(valInFloat < parseFloat(this.minValue) || (isNaN(valInFloat) && e.key === "0")) { 
     e.preventDefault(); 
     } 
    } 

    if(this.maxValue.length) { 
     if(valInFloat > parseFloat(this.maxValue)) { 
     e.preventDefault(); 
     } 
    } 

    if (this.DecimalPlaces) { 
     let currentCursorPos: number = -1;  
     if (typeof this.elemRef.nativeElement.selectionStart == "number") { 
      currentCursorPos = this.elemRef.nativeElement.selectionStart; 
     } else { 
     // Probably an old IE browser 
     console.log("This browser doesn't support selectionStart"); 
     } 

     let dotLength: number = e.target.value.replace(/[^\.]/g, '').length 
     // If user has not entered a dot(.) e.target.value.split(".")[1] will be undefined 
     let decimalLength = e.target.value.split(".")[1] ? e.target.value.split(".")[1].length : 0; 

     // (this.DecimalPlaces - 1) because we don't get decimalLength including currently pressed character 
     // currentCursorPos > e.target.value.indexOf(".") because we must allow user's to enter value before dot(.) 
     // Checking Backspace etc.. keys because firefox doesn't pressing them while chrome does by default 
     if(dotLength > 1 || (dotLength === 1 && e.key === ".") || (decimalLength > (parseInt(this.DecimalPlaces) - 1) && 
     currentCursorPos > e.target.value.indexOf(".")) && ["Backspace", "ArrowLeft", "ArrowRight"].indexOf(e.key) === -1) { 
     e.preventDefault(); 
     } 
    } 
    } 
} 

的HTML用法如下:

<input type="text" OnlyNumber="true" DecimalPlaces="2" minValue="1.00" maxValue="999999999.00"> 

如果您发现任何错误,它请让我知道在下面的意见。

P.S:此指令在此answer上进行了改进,以验证小数点。

+0

在Chrome(版本58.0.3029.110)上,Angular 2.4.0 - 小数点检查不起作用(this.elemRef.nativeElement.selectionStart为空)。但是,否则真的很干净的指令。 – nbo

+0

谢谢。我在OS X El Capitan上使用Angular 4.0.0和chrome 57.0.2987.133(64位)。我修复了一个Firefox的bug,现在它也在Firefox v53上工作。如果您找到解决方法,请随时提出编辑 – Dhyey

+0

@Dhyey如果您键入小数点数字,并选择或突出显示小数点后的最后一位数字,并尝试用另一个数字替换它,则不起作用。 – absingharora

相关问题