Help with a custom input mask that works with ion-input


#1

I’ve been at this off and on for a couple days trying to find a way to get a custom input masking directive to work with the ion-input component.

I found a github thread here that was about getting something similar working for a credit card input directive. But this one was added to a normal input element and I would very much like to get some of the label functionality included with ion-input and ion-label and those don’t work with a normal input element

So I was going to just start from that directive example which has a plunker here but I’m already stuck with the error

Can't bind to 'mask' since it isn't a known property of 'ion-input'

Here is what my directive looks like so far

import { Directive, forwardRef, ElementRef, Renderer, Attribute } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

const Mask : string = '(999) 999.9999';

export const CUSTOM_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => InputMaskDirective),
  multi: true
};

@Directive({
  selector: '[mask]', // Attribute selector
  providers: [CUSTOM_VALUE_ACCESSOR]
})
export class InputMaskDirective implements ControlValueAccessor {

  onChange = (_: any) => { };
  onTouched = () => { };

  pattern: string;

  constructor(
    private renderer: Renderer,
    private elementRef: ElementRef,
    @Attribute('mask') pattern: string) {
      this.pattern = pattern;
    }

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

  registerOnTouched(fn: () => any): void { this.onTouched = fn; }


  writeValue(value: any): void {
    // Write to view
    if (value !== null && value !== undefined) {

      // value = VMasker.toPattern(value, Mask);

      console.log(value);

      this.renderer.setElementProperty(this.elementRef.nativeElement, 'value', value);
    }
  }

  input(elt) {
    // prevent user to input non-digit characters while typing
    // and limit user input to CardMaskLength characters
    let val = elt.value.replace(/\D/g, '');

    //write formatted to control view
    this.writeValue(val);

    // Write back to model (number)
    this.onChange(val);
  }
}

And in the template I am just doing

[mask]="'(***) ***.****'"

I realize this doesn’t yet use the mask I pass in but I just needed it to recognize input and such and I’m already stuck there.

I have added this module in the declarations of my app.module.ts, and also tried to import it into my pages .ts file just in case but it still won’t allow me to add this attribute. Is there something else with this code that’s causing the issue?


#2

Hey, did you have any luck figuring this out? I’m having the same problem.

I looked into the angular2-text-mask package here: https://github.com/text-mask/text-mask/tree/master/angular2 There’s a note at the bottom saying it can’t work with ionic because ionic overrides ControlValueAccessor.

I also found this thread where people were mentioning it works with version 8.0.2 https://github.com/ionic-team/ionic/issues/13194 - not later versions. I tried this and the mask almost worked but it has some bugs by being off by one character.


#3

Is there a fix to the one character that is off.?