如何以角度格式化数字输入 [英] How to format number input in angular

查看:30
本文介绍了如何以角度格式化数字输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的数字输入

我想要这样的东西(不管分隔符是什么)

我的实际代码如下:

<div class="col-xs-12 col-md-10"><mat-form-field><input [disabled]="item.lock!=0" type="number" matInput [placeholder]="item.name" [(ngModel)]="item.concept" ></mat-form-field>

我怎样才能做到这一点?

解决方案

我遇到了类似的问题.为了解决这个问题,我使用了这篇 文章.我创建了一个稍微修改过的版本以满足我的需要.

import { Directive, ElementRef, forwardRef, HostListener, Input, OnDestroy } from '@angular/core';从@angular/forms"导入 { ControlValueAccessor, NG_VALUE_ACCESSOR };从@angular/material"导入{MAT_INPUT_VALUE_ACCESSOR};从'rxjs'导入{订阅};从 '@angular/common' 导入 { formatNumber };@指示({选择器:'输入[localizedNumericInput]',供应商: [{ 提供:MAT_INPUT_VALUE_ACCESSOR,useExisting:LocalizedNumericInputDirective },{提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => LocalizedNumericInputDirective),多:真}]})导出类 LocalizedNumericInputDirective 实现 ControlValueAccessor、OnDestroy {语言环境 = 'en';十进制标记:字符串;构造函数(私有元素:ElementRef){}私有 _value: 字符串 |空值;获取值():字符串 |空值 {返回 this._value;}@Input('值')设置值(值:字符串 | null){this._value = 值;this.formatValue(value);}@HostListener('input', ['$event.target.value'])输入(值){//查找所有数字、小数点标记(, or .) 和 -//它会删除千位分隔符 因为它总是与小数点相反const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');//小数点前后的分隔值const [整数,十进制] = value.replace(regExp, '').split(this.decimalMarker);//发送非本地化值,点为decimalMarker给APIthis._value = 十进制?integer.concat('.', decimal) : 整数;//如果小数点分隔符是最后一个字符,则不更新//因为它会删除 .||,如果(this.isLastCharacterDecimalSeparator(值)){this._value = 值;}//这里通知 Angular Validatorsthis._onChange(this._value);}@HostListener('模糊')_onBlur() {/*** 添加千位分隔符*/this.formatValue(this._value);}@HostListener('焦点')焦点(){this.unFormatValue();}_onChange(value: any): void {}/*** @参数值* 在赋值时应用格式*/写值(值:任何){this._value = 值;this.formatValue(this._value);}registerOnChange(fn: (value: any) => void) {this._onChange = fn;}registerOnTouched() {}isLastCharacterDecimalSeparator(值:任何){返回 isNaN(value[value.length - 1]);}私有格式值(值:字符串 | null){如果(值 === 空){this.element.nativeElement.value = '';返回;}如果(this.isLastCharacterDecimalSeparator(值)){this.element.nativeElement.value = value;返回;}//结束语言环境中的小数点和千位分隔符const [thousandSeparator, decimalMarker] = formatNumber(1000.99, this.locale).replace(/\d/g, '');this.decimalMarker = 十进制标记;//这里的值应该总是与 .作为小数点标记,因此任何其他行为都是错误const [整数,十进制] = value.split('.');//每三个元素分组,并在它们后面添加千位分隔符this.element.nativeElement.value = integer.replace(/\B(?=(\d{3})+(?!\d))/g,千分隔符);//添加小数和decimalMarker(如果有)如果(十进制){this.element.nativeElement.value = this.element.nativeElement.value.concat(decimalMarker, decimal);}}私人 unFormatValue() {const value = this.element.nativeElement.value;如果(this.isLastCharacterDecimalSeparator(值)){返回;}const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');const [整数,十进制] = value.replace(regExp, '').split(this.decimalMarker);this._value = integer.concat('.', decimal);如果(值){this.element.nativeElement.value = this._value;} 别的 {this.element.nativeElement.value = '';}}}

I have a number input like this

and i want something like this (no matters what the sepparator will be)

My actual code works as follows:

<div class="row center-xs" *ngFor="let item of listItem;let i=index">
    <div class="col-xs-12 col-md-10">
        <mat-form-field>
            <input [disabled]="item.lock!=0" type="number" matInput [placeholder]="item.name" [(ngModel)]="item.concept" >                                      
        </mat-form-field>
    </div>
</div>

How can i achieve this?

解决方案

I had a similar problem. To solve it I have used this article. I have created a slightly modified version to fit my needs.

import { Directive, ElementRef, forwardRef, HostListener, Input, OnDestroy } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material';
import { Subscription } from 'rxjs';
import { formatNumber } from '@angular/common';

@Directive({
  selector: 'input[localizedNumericInput]',
  providers: [
    { provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: LocalizedNumericInputDirective },
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => LocalizedNumericInputDirective),
      multi: true
    }
  ]
})
export class LocalizedNumericInputDirective implements ControlValueAccessor, OnDestroy {
  locale = 'en';
  decimalMarker: string;

  constructor(private element: ElementRef<HTMLInputElement>) {
  }

  private _value: string | null;

  get value(): string | null {
    return this._value;
  }

  @Input('value')
  set value(value: string | null) {
    this._value = value;
    this.formatValue(value);
  }

  @HostListener('input', ['$event.target.value'])
  input(value) {
    //Find all numerics, decimal marker(, or .) and -
    //It will delete thousandSeparator cos it's always opposite to decimal marker
    const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');
    //Separate value on before and after decimal marker
    const [integer, decimal] = value.replace(regExp, '').split(this.decimalMarker);

    //Send non localized value, with dot as decimalMarker to API
    this._value = decimal ? integer.concat('.', decimal) : integer;

    // If decimal separator is last character don't update
    // because it will delete . || ,
    if (this.isLastCharacterDecimalSeparator(value)) {
      this._value = value;
    }

    // here to notify Angular Validators
    this._onChange(this._value);
  }

  @HostListener('blur')
  _onBlur() {
    /**
     * Adding thousand separators
     */
    this.formatValue(this._value);
  }

  @HostListener('focus')
  onFocus() {
    this.unFormatValue();
  }

  _onChange(value: any): void {}

  /**
   * @param value
   * apply formatting on value assignment
   */
  writeValue(value: any) {
    this._value = value;
    this.formatValue(this._value);
  }

  registerOnChange(fn: (value: any) => void) {
    this._onChange = fn;
  }

  registerOnTouched() {}

  isLastCharacterDecimalSeparator(value: any) {
    return isNaN(value[value.length - 1]);
  }


  private formatValue(value: string | null) {
    if (value === null) {
      this.element.nativeElement.value = '';
      return;
    }

    if (this.isLastCharacterDecimalSeparator(value)) {
      this.element.nativeElement.value = value;
      return;
    }

    // Conclude the decimal and thousand separators from locale
    const [thousandSeparator, decimalMarker] = formatNumber(1000.99, this.locale).replace(/\d/g, '');
    this.decimalMarker = decimalMarker;

    //Here value should always come with . as decimal marker thus any other behavior is bug
    const [integer, decimal] = value.split('.');

    //Group every three elements, and add thousandSeparator after them
    this.element.nativeElement.value = integer.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);

    //Add decimals and decimalMarker if any
    if (decimal) {
      this.element.nativeElement.value = this.element.nativeElement.value.concat(decimalMarker, decimal);
    }
  }

  private unFormatValue() {
    const value = this.element.nativeElement.value;
    if (this.isLastCharacterDecimalSeparator(value)) {
      return;
    }
    const regExp = new RegExp(`[^\\d${this.decimalMarker}-]`, 'g');
    const [integer, decimal] = value.replace(regExp, '').split(this.decimalMarker);

    this._value = integer.concat('.', decimal);
    if (value) {
      this.element.nativeElement.value = this._value;
    } else {
      this.element.nativeElement.value = '';
    }
  }
}

这篇关于如何以角度格式化数字输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆