0

I was wondering if it's possible to restrict an input field to a certain format like for example as many digits as you want then "." and then 2 digits? That's basically an input for a price... And I don't want a simple validation like the pattern attribute. I want the user to not be able to make a false input.

Kajot
  • 1,043
  • 2
  • 15
  • 22

2 Answers2

5

you need use a directive. In the directive add a hotListener about input and check if match with the regExpr indicated. I make a directive mask some time ago. The directive in the stackblitz, with the edvertisment that the code is provide "as is" without warranty of any kind.

@Directive({
  selector: '[mask]'
})
export class MaskDirective {
  @Input()
  set mask(value) {
    this.regExpr = new RegExp(value);
  }

  private _oldvalue: string = "";
  private regExpr: any;
  private control: NgControl;
  constructor(injector: Injector) {
    //this make sure that not error if not applied to a NgControl
    try {
      this.control = injector.get(NgControl)
    }
    catch (e) {
    }
  }
  @HostListener('input', ['$event'])
  change($event) {

    let item = $event.target
    let value = item.value;
    let pos = item.selectionStart; //get the position of the cursor
    let matchvalue = value;
    let noMatch: boolean = (value && !(this.regExpr.test(matchvalue)));
    if (noMatch) {
      item.selectionStart = item.selectionEnd = pos - 1;
      if (item.value.length < this._oldvalue.length && pos == 0)
        pos = 2;
      if (this.control)
        this.control.control.setValue(this._oldvalue, { emit: false });

      item.value = this._oldvalue;
      item.selectionStart = item.selectionEnd = pos - 1; //recover the position
    }
    else
      this._oldvalue = value;
  }
}

Be carefull, when you write "mask" in a string (or in the html). e.g. for a number width two decimals is:

[mask]="'^[+-]?([1-9]\\d*|0)?(\\.\\d\{0,2\})?$'"

(the \ must be writed as \\, { as \{, } as \} ...)

Eliseo
  • 50,109
  • 4
  • 29
  • 67
1

you can use an HTML5 feature, regex input

with regex pattern validation:

<input type="text" name="weight" value="" pattern="^[1-9]\d{0,*}\.\d{2}$" />

you can also use this library, decorate your input with the key :

<input type="text" pattern="[0-9]+" ng-pattern-restrict /> 

the repo :github.com/AlphaGit/ng-pattern-restrict

Ganz
  • 76
  • 4
  • Thats exactly what im not looking for... I want the user to not be able to make a false input! With your suggestion im still able to make false inputs... – Kajot Jan 31 '19 at 13:47
  • @Kai you can use this use the library and decorate your input with the key : **** the repo :https://github.com/AlphaGit/ng-pattern-restrict – Ganz Jan 31 '19 at 14:01
  • i installed it and added it to my app.module but now I get a error "ReferenceError: angular ist not defined" – Kajot Jan 31 '19 at 14:24
  • it depend on your angular version use : https://github.com/AlphaGit/a-pattern-restrict for 2+ – Ganz Jan 31 '19 at 14:27
  • doesnt work... I copied the a-pattern-restrict.ts into my project as it tells me to do and then i importet it in my app.module. But it doesnt do anything... – Kajot Jan 31 '19 at 14:37