RobinHerbots / Inputmask

Input Mask plugin
https://robinherbots.github.io/Inputmask/
MIT License
6.39k stars 2.17k forks source link

Angular2, inputmask ngModel binding #1317

Open FRAGnatt opened 8 years ago

FRAGnatt commented 8 years ago

Hello everyone, I have some problem with ng2 ang inputmask. For example I have had this code component.html `

                <input type="text" [(ngModel)]="sender.phone" class="form-control" id="sender-phone" placeholder="Phone">
            </div>`

component.ts ngAfterViewInit() { let phoneNumberInput = document.getElementById('sender-phone'); let inputmask = new Inputmask('+7(999)999-99-99'); inputmask.mask(element); }

Inputmask is working good. But my [(ngModel)] didn't work. Anyone know how I can resolve my issue ?

My code for example http://plnkr.co/edit/F3pob7hH2ZrJv0MDNa9x?p=preview

qwding commented 8 years ago

I have the same problem. Have you resolve it?

FRAGnatt commented 8 years ago

Yes, I have. http://plnkr.co/edit/tN6y5d2fsl0b7cRq6Prv?p=preview

I created directive with Input Mask ` @Directive({ selector: '[tdInputmask]' }) export class InputmaskDirective { @Output('tdInputmaskUnmaskedValue') unmaskedValueEmitter = new EventEmitter();

@Input() set defaultValue (value: string) {
    //this._defaultColor = colorName || this._defaultColor;
}

@Input('tdInputmask') mask: string;

private el: HTMLElement;
constructor(el: ElementRef) {
    this.el = el.nativeElement;
}

ngAfterViewInit() {
   let inputmask = new Inputmask(this.mask);
    let elementCallback = () =>  {
        if (this.el.inputmask) {
            this.unmaskedValueEmitter.emit('7' + this.el.inputmask.unmaskedvalue());
            //if (!this.el.inputmask.isComplete()) {
            //    this.el.parentElement.classList.add('has-error');
            //} else {
            //    this.el.parentElement.classList.remove('has-error');
            //}
        }
    };

    inputmask.opts.oncomplete = elementCallback;
    inputmask.opts.onincomplete = elementCallback;
    inputmask.opts.onBeforePaste = (pastedValue: string) => {
        if (pastedValue[0] == '7' || pastedValue[0] == '8') {
            return pastedValue.slice(1);
        }
        return pastedValue;
    };
    inputmask.mask(this.el);
}

}`

And in HTML code I use <input [tdInputmask]="'+7(999)999-99-99'" (tdInputmaskUnmaskedValue)="val3 = $event">

qwding commented 8 years ago

I use inputmask through primeng(http://www.primefaces.org/primeng/#/mask). I decided to use it later until it is fixed. thx~

omeralper commented 7 years ago

A temporary solution:

import { Directive, ElementRef, Input,Output, Renderer,EventEmitter,AfterViewInit } from 'angular2/core';

@Directive({
    selector: '[mask]',
})

export class MaskDirective implements AfterViewInit{

    @Output() ngModelChange: EventEmitter<any> = new EventEmitter(false);
    @Input('mask') mask:string;

    constructor(private el: ElementRef,private renderer: Renderer) {

    }

    ngAfterViewInit() {
        let el = <HTMLInputElement>this.el.nativeElement;       
            $(el).inputmask(
                {
                    "alias": this.mask,
                    "oncomplete": () => {
                        this.ngModelChange.emit(el.value); 
                    }
                });

    }
}

<input [mask]="'ip'"  [(ngModel)]="ip">
egucciar commented 7 years ago

how to get this working with autoUnmask: true option?

gregmagolan commented 6 years ago

This directive worked for me with Angular 5 dynamic forms. Haven't tried it with [(ngModel)] style template driven forms but I think it would work the same with those.

import {Directive, ElementRef, Input, OnDestroy, Optional} from '@angular/core';
import {NgControl} from '@angular/forms';

@Directive({
  selector: '[inputMask]',
})
export class InputMaskDirective implements OnDestroy {

  @Input('inputMask')
  mask: string;

  @Input('inputMaskOptions')
  options: any;

  constructor(
    private elementRef: ElementRef,
    @Optional() private control: NgControl,
  ) {}

  ngOnChanges(): void {
    if (!this.control) {
      console.warn('No control for InputMaskDirective');
      return;
    }

    if (this.mask) {
      let options: any = _.clone(this.options) || {};
      _.defaults(options, { showMaskOnHover: false });
      options.oncomplete = options.onincomplete = options.oncleared = () => this.handleChange();
      Inputmask(this.mask, options).mask(this.elementRef.nativeElement);
    } else {
      Inputmask.remove(this.elementRef.nativeElement);
    }
  }

  private handleChange(): void {
    this.control.control.patchValue(this.elementRef.nativeElement.value);
  }
}

Usage (with dynamic forms) is like this:

<input formControlName="phoneNumber" inputMask="(999)-999-9999">

May help someone.

gregmagolan commented 6 years ago

And this is a similar directive for restrict input:

import {Directive, ElementRef, Input, Optional} from '@angular/core';
import {NgControl} from '@angular/forms';

@Directive({
  selector: '[restrictInput]',
})
export class RestrictInputDirective {
  private regexMap: { [key: string]: string } = {
    'integer': '^[+-]?[0-9]*$',
    'positive-integer': '^[0-9]*$',
    'float': '^[+-]?([0-9]*[.])?[0-9]+$',
    'positive-float': '^([0-9]*[.])?[0-9]+$',
    'amount': '^[+-]?([0-9]*[.])?[0-9]?[0-9]?$',
    'positive-amount': '^([0-9]*[.])?[0-9]?[0-9]?$',
    'words': '([A-z]*\\s)*',
  };

  @Input('restrictInput')
  mask: any;

  @Input('restrictInputOptions')
  options: any;

  constructor(
    private elementRef: ElementRef,
    @Optional() private control: NgControl,
  ) {}

  ngOnChanges(): void {
    if (!this.control) {
      console.warn('No control for RestrictInputDirective');
      return;
    }

    if (this.mask) {
      let options: any = _.clone(this.options) || {};
      _.defaults(options, { showMaskOnHover: false, placeholder: '' });
      options.regex = this.regexMap[this.mask] || this.mask;
      options.oncomplete = options.onincomplete = options.oncleared = () => this.handleChange();
      Inputmask(options).mask(this.elementRef.nativeElement);
    } else {
      Inputmask.remove(this.elementRef.nativeElement);
    }
  }

  private handleChange(): void {
    this.control.control.patchValue(this.elementRef.nativeElement.value);
  }
}

Usage like so:

<input formControlName="cost" placeholder="Cost" restrictInput="positive-amount">
gonzalocast17 commented 6 years ago

where do you take Inputmask?

gregmagolan commented 6 years ago

where do you take Inputmask?

Its an @Input on the inputMask directive:

<input formControlName="phoneNumber" inputMask="(999)-999-9999">

rakeshnayak360 commented 5 years ago

Hi @gregmagolan , I imported InputMaskDirective in my app-routing.module.ts file and declared in @NgModule({declarations: [InputMaskDirective] }). And my input box is <input type="text" inputMask="(999)-999-9999" />. Still it is not working. Where m I going wrong?