Skip to content

Instantly share code, notes, and snippets.

@JoeMeeks
Last active October 25, 2020 13:44
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save JoeMeeks/e7932fa291ba1c7e1e66597e5b52c633 to your computer and use it in GitHub Desktop.
Save JoeMeeks/e7932fa291ba1c7e1e66597e5b52c633 to your computer and use it in GitHub Desktop.
Custom Ionic 2 & 3 Input Mask Directive
<ion-input type="tel" pattern="\d*" placeholder="(xxx) xxx-xxxx" mask="(***) ***-****" [(ngModel)]="phone" name="phone"></ion-input>
<ion-input type="tel" pattern="\d*" placeholder="xxx-xx-xxxx" mask="***-**-****" [(ngModel)]="ssn" name="ssn"></ion-input>
import { Directive, Attribute } from '@angular/core';
@Directive({
selector: '[mask]',
host: {
'(keyup)': 'onInputChange($event)'
}
})
export class InputMask {
pattern: string;
constructor(
@Attribute('mask') pattern: string
) {
this.pattern = pattern;
}
onInputChange(e) {
try {
let value = e.target.value,
caret = e.target.selectionStart,
pattern = this.pattern,
reserve = pattern.replace(/\*/, 'g'),
applied = '',
ordinal = 0;
if (e.keyCode === 8 || e.key === 'Backspace' || e.keyCode === 46 || e.key === 'Delete') {
if (value.length) {
//remove all trailing formatting
while (value.length && pattern[value.length] && pattern[value.length] !== '*') {
value = value.substring(0, value.length - 1);
}
//remove all leading formatting to restore placeholder
if (pattern.substring(0, value.length).indexOf('*') < 0) {
value = value.substring(0, value.length - 1);
}
}
}
//apply mask characters
for (var i = 0; i < value.length; i++) {
//enforce pattern limit
if (i < pattern.length) {
//match mask
if (value[i] === pattern[ordinal]) {
applied += value[i];
ordinal++;
} else if (reserve.indexOf(value[i]) > -1) {
//skip other reserved characters
} else {
//apply leading formatting
while (ordinal < pattern.length && pattern[ordinal] !== '*') {
applied += pattern[ordinal];
ordinal++;
}
applied += value[i];
ordinal++;
//apply trailing formatting
while (ordinal < pattern.length && pattern[ordinal] !== '*') {
applied += pattern[ordinal];
ordinal++;
}
}
}
}
e.target.value = applied;
if (caret < value.length) {
e.target.setSelectionRange(caret, caret);
}
} catch (ex) {
console.error(ex.message);
}
}
}
@JoeMeeks
Copy link
Author

@BlacksmithVRS my GitHub notification settings were not letting me know about mentions so I apologize for the late reply. Have you tried:

<ion-input type="tel" pattern="\d*" placeholder="(xxx) xxx-xxxx" [mask]="publicMaskVar" [(ngModel)]="phone" name="phone"></ion-input>

with publicMaskVar being assigned with the (ionChange) handler of your radio input?

@JoeMeeks
Copy link
Author

@codinconan nice ngAfterViewInit implementation!

@mapplics
Copy link

thanks man! you saved my day!

@jscarl
Copy link

jscarl commented Sep 3, 2018

@JoeMeeks nice work, how to use this directive for thousand separator?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment