在Angular 6中仅允许带小数的正数

时间:2019-07-22 17:38:45

标签: angular typescript

我是堆栈溢出的新手,所以如果我在任何地方出错,请原谅我。我对Angular 6中的问题感到困惑,我几乎没有输入任何类型为数字和文本的输入字段,并且我想阻止用户输入除“。”以外的任何字符。 (点),并且只能输入带有一个点的正数,例如。 “ 1.22”而非“ 1..2。”或“ -1.12”或“ -111”。

我尝试过(keyup),(keypress)和(keydown),但它们每个对我来说都确实令人困惑。如果有任何指令或解决方案,请提出建议。 在html

 <input type="number"(keyup)="numberOnlyWithDecimal($event,xyz)" name="weight [(ngModel)]="xyz" min="0" step="0.1">

在.ts

public textlength=0;


numberOnlyWithDecimal(event, text): boolean {

var regex = /^\d+(\.\d+)?$/;
const charCode = (event.which) ? event.which : event.keyCode;
var text2 = text + ''
var test = text2.split(".")
if (text2) {  
  this.textlength = test.length-1 ;
}
if(text == null && charCode == 46){
  return false;
}

if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57)) {
  return false;
}
if (!regex.test(charCode)) {
  return false
}
if (charCode === 46 && this.textlength ===1 ) {
  return false
}
return true;

}

3 个答案:

答案 0 :(得分:1)

在这里,为您提供完整的工作解决方案:

1)指令


@Directive({
  selector: '[appNumbersOnly]'
})
export class NumbersOnlyDirective {

  private regex: RegExp = new RegExp(/^-?[0-9]+(\.[0-9]*){0,1}$/g);
  private specialKeys: Array<string> = ['Backspace', 'Tab'];

  constructor(private el: ElementRef) {
  }
  @HostListener('keydown', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    if (this.specialKeys.indexOf(event.key) !== -1) {
      return;
    }
    const current: string = this.el.nativeElement.value;
    const next: string = current.concat(event.key);
    if (next && !String(next).match(this.regex)) {
      event.preventDefault();
    }
  }
}

2)在html中的用法

<input type="text" name="weight" appNumbersOnly [(ngModel)]="xyz"  />

Stackblitz在这里供参考

答案 1 :(得分:0)

您可以创建自定义指令

import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
  selector: '[appTwoDigitDecimaNumber]'
})

export class TwoDigitDecimaNumberDirective {
  private regex: RegExp = new RegExp(/^\d*\.?\d{0,2}$/g);
  private specialKeys: Array<string> = ['Backspace', 'Tab', 'End', 'Home', '-'];

  @Input('appTwoDigitDecimaNumber') decimal:any;

  constructor(private el: ElementRef) {
  }
  @HostListener('keydown', ['$event'])

  onKeyDown(event: KeyboardEvent) {
    // Allow Backspace, tab, end, and home keys
    if(this.decimal){  
      if (this.specialKeys.indexOf(event.key) !== -1) {
        return;
      }
      let current: string = this.el.nativeElement.value;
      let next: string = current.concat(event.key);
      if (next && !String(next).match(this.regex)) {
        event.preventDefault();
      }
    }else{
      const charCode = (event.which) ? event.which : event.keyCode;
      if (charCode > 31 && (charCode < 48 || charCode > 105)) {
        event.preventDefault();
      }
      return;
    }
  }

用法

<input type="text" [appTwoDigitDecimaNumber]="true">

我希望它将对您有很大帮助。

注意:您可以在要使用的任何number类型字段中使用它,如果不想使用,只需添加[appTwoDigitDecimaNumber]="true",然后添加[appTwoDigitDecimaNumber]="false"。 因为我已经以动态形式使用了这些指令,所以我为什么将其基于truefalse进行设置。 您也可以在Dynamic form中使用它

答案 2 :(得分:0)

最后,经过大量的头脑风暴,我找到了一个可行的解决方案。我要感谢大家的帮助,你们是救世主。

我使用了@yanky_cranky代码并对其进行了一些修改,并且适用于数字和文本输入类型。这是代码。

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

struct data_t {         /* simple struct to coordinate data for each city */
    int x, y, id;
    std::string name;
};

int main (int argc, char **argv) {

    if (argc < 2) { /* validate argument given for filename */
        std::cerr << "error: filename required as 1st argument.\n";
        return 1;
    }

    std::string line;           /* string to hold each line read from file */
    std::vector<data_t> data;   /* vector of struct data_t to hold data */
    std::ifstream f (argv[1]);  /* open filename given for reading */

    while (getline (f, line)) {         /* read each line of file into line */
        data_t dtmp;                    /* temp data struct */
        std::string stmp;               /* temp string for parsing */
        std::stringstream ss (line);    /* create stringstream from line */

        /* read/discard [ */
        if (!getline (ss, stmp, '[')) {
            std::cerr << "error: invalid format before - x.\n";
            continue;
        }
        if (!(ss >> dtmp.x)) {      /* read x from stringstream */
            std::cerr << "error: invalid format - x.\n";
            continue;
        }

        /* read/discard , */
        if (!getline (ss, stmp, ',')) {
            std::cerr << "error: invalid format before - y.\n";
            continue;
        }
        if (!(ss >> dtmp.y)) {      /* read y from stringstream */
            std::cerr << "error: invalid format - y.\n";
            continue;
        }

        if (!getline (ss, stmp, '-')) { /* read/discard - */
            std::cerr << "error: invalid format before - id.\n";
            continue;
        }
        if (!(ss >> dtmp.id)) {     /* read id from stringstream */
            std::cerr << "error: invalid format - id.\n";
            continue;
        }

        if (!getline (ss, stmp, '-')) { /* read/discard - */
            std::cerr << "error: invalid format before - name.\n";
            continue;
        }
        if (!(ss >> dtmp.name)) {   /* read name from stringstream */
            std::cerr << "error: invalid format - name.\n";
            continue;
        }

        data.push_back(dtmp);   /* add temp struct to vector of struct */
    }

    for (auto& d : data)    /* output all stored data */
        std::cout << "x: " << d.x << "  y: " << d.y << "  id: " << d.id
                << "  name: " << d.name << '\n';
}

指令:

$ cat dat/xyid.txt
[1, 1]-3-Big_City
[2, 8]-2-Mid_City