1

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.

1
  • Did you try directives? Commented Jan 31, 2019 at 13:06

2 Answers 2

8

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 \} ...)

Sign up to request clarification or add additional context in comments.

Comments

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

5 Comments

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...
@Kai you can use this use the library and decorate your input with the key : <input type="text" pattern="[0-9]+" ng-pattern-restrict /> the repo :github.com/AlphaGit/ng-pattern-restrict
i installed it and added it to my app.module but now I get a error "ReferenceError: angular ist not defined"
it depend on your angular version use : github.com/AlphaGit/a-pattern-restrict for 2+
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...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.