915 lines
99 KiB
JavaScript
915 lines
99 KiB
JavaScript
|
/*
|
||
|
Port of jQuery MaskedInput by DigitalBush as a Native Angular2 Component in Typescript without jQuery
|
||
|
https://github.com/digitalBush/jquery.maskedinput/
|
||
|
|
||
|
Copyright (c) 2007-2014 Josh Bush (digitalbush.com)
|
||
|
|
||
|
Permission is hereby granted, free of charge, to any person
|
||
|
obtaining a copy of this software and associated documentation
|
||
|
files (the "Software"), to deal in the Software without
|
||
|
restriction, including without limitation the rights to use,
|
||
|
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
copies of the Software, and to permit persons to whom the
|
||
|
Software is furnished to do so, subject to the following
|
||
|
conditions:
|
||
|
|
||
|
The above copyright notice and this permission notice shall be
|
||
|
included in all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||
|
*/
|
||
|
import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common';
|
||
|
import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, Inject, Input, NgModule, Output, PLATFORM_ID, ViewChild, ViewEncapsulation, booleanAttribute, forwardRef, numberAttribute } from '@angular/core';
|
||
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
||
|
import { PrimeTemplate, SharedModule } from 'primeng/api';
|
||
|
import { AutoFocusModule } from 'primeng/autofocus';
|
||
|
import { DomHandler } from 'primeng/dom';
|
||
|
import { TimesIcon } from 'primeng/icons/times';
|
||
|
import { InputTextModule } from 'primeng/inputtext';
|
||
|
import * as i0 from "@angular/core";
|
||
|
import * as i1 from "primeng/api";
|
||
|
import * as i2 from "@angular/common";
|
||
|
import * as i3 from "primeng/inputtext";
|
||
|
import * as i4 from "primeng/autofocus";
|
||
|
export const INPUTMASK_VALUE_ACCESSOR = {
|
||
|
provide: NG_VALUE_ACCESSOR,
|
||
|
useExisting: forwardRef(() => InputMask),
|
||
|
multi: true
|
||
|
};
|
||
|
/**
|
||
|
* InputMask component is used to enter input in a certain format such as numeric, date, currency, email and phone.
|
||
|
* @group Components
|
||
|
*/
|
||
|
export class InputMask {
|
||
|
document;
|
||
|
platformId;
|
||
|
el;
|
||
|
cd;
|
||
|
config;
|
||
|
/**
|
||
|
* HTML5 input type.
|
||
|
* @group Props
|
||
|
*/
|
||
|
type = 'text';
|
||
|
/**
|
||
|
* Placeholder character in mask, default is underscore.
|
||
|
* @group Props
|
||
|
*/
|
||
|
slotChar = '_';
|
||
|
/**
|
||
|
* Clears the incomplete value on blur.
|
||
|
* @group Props
|
||
|
*/
|
||
|
autoClear = true;
|
||
|
/**
|
||
|
* When enabled, a clear icon is displayed to clear the value.
|
||
|
* @group Props
|
||
|
*/
|
||
|
showClear = false;
|
||
|
/**
|
||
|
* Inline style of the input field.
|
||
|
* @group Props
|
||
|
*/
|
||
|
style;
|
||
|
/**
|
||
|
* Identifier of the focus input to match a label defined for the component.
|
||
|
* @group Props
|
||
|
*/
|
||
|
inputId;
|
||
|
/**
|
||
|
* Style class of the input field.
|
||
|
* @group Props
|
||
|
*/
|
||
|
styleClass;
|
||
|
/**
|
||
|
* Advisory information to display on input.
|
||
|
* @group Props
|
||
|
*/
|
||
|
placeholder;
|
||
|
/**
|
||
|
* Size of the input field.
|
||
|
* @group Props
|
||
|
*/
|
||
|
size;
|
||
|
/**
|
||
|
* Maximum number of character allows in the input field.
|
||
|
* @group Props
|
||
|
*/
|
||
|
maxlength;
|
||
|
/**
|
||
|
* Specifies tab order of the element.
|
||
|
* @group Props
|
||
|
*/
|
||
|
tabindex;
|
||
|
/**
|
||
|
* Title text of the input text.
|
||
|
* @group Props
|
||
|
*/
|
||
|
title;
|
||
|
/**
|
||
|
* Specifies the input variant of the component.
|
||
|
* @group Props
|
||
|
*/
|
||
|
variant = 'outlined';
|
||
|
/**
|
||
|
* Used to define a string that labels the input element.
|
||
|
* @group Props
|
||
|
*/
|
||
|
ariaLabel;
|
||
|
/**
|
||
|
* Establishes relationships between the component and label(s) where its value should be one or more element IDs.
|
||
|
* @group Props
|
||
|
*/
|
||
|
ariaLabelledBy;
|
||
|
/**
|
||
|
* Used to indicate that user input is required on an element before a form can be submitted.
|
||
|
* @group Props
|
||
|
*/
|
||
|
ariaRequired;
|
||
|
/**
|
||
|
* When present, it specifies that the element value cannot be altered.
|
||
|
* @group Props
|
||
|
*/
|
||
|
disabled;
|
||
|
/**
|
||
|
* When present, it specifies that an input field is read-only.
|
||
|
* @group Props
|
||
|
*/
|
||
|
readonly;
|
||
|
/**
|
||
|
* Defines if ngModel sets the raw unmasked value to bound value or the formatted mask value.
|
||
|
* @group Props
|
||
|
*/
|
||
|
unmask;
|
||
|
/**
|
||
|
* Name of the input field.
|
||
|
* @group Props
|
||
|
*/
|
||
|
name;
|
||
|
/**
|
||
|
* When present, it specifies that an input field must be filled out before submitting the form.
|
||
|
* @group Props
|
||
|
*/
|
||
|
required;
|
||
|
/**
|
||
|
* Regex pattern for alpha characters
|
||
|
* @group Props
|
||
|
*/
|
||
|
characterPattern = '[A-Za-z]';
|
||
|
/**
|
||
|
* When present, the input gets a focus automatically on load.
|
||
|
* @group Props
|
||
|
*/
|
||
|
autofocus;
|
||
|
/**
|
||
|
* When present, the input gets a focus automatically on load.
|
||
|
* @group Props
|
||
|
* @deprecated Use autofocus property instead.
|
||
|
*/
|
||
|
set autoFocus(value) {
|
||
|
this.autofocus = value;
|
||
|
console.warn('autoFocus is deprecated. Use autofocus property instead.');
|
||
|
}
|
||
|
/**
|
||
|
* Used to define a string that autocomplete attribute the current element.
|
||
|
* @group Props
|
||
|
*/
|
||
|
autocomplete;
|
||
|
/**
|
||
|
* When present, it specifies that whether to clean buffer value from model.
|
||
|
* @group Props
|
||
|
*/
|
||
|
keepBuffer = false;
|
||
|
/**
|
||
|
* Mask pattern.
|
||
|
* @group Props
|
||
|
*/
|
||
|
get mask() {
|
||
|
return this._mask;
|
||
|
}
|
||
|
set mask(val) {
|
||
|
this._mask = val;
|
||
|
this.initMask();
|
||
|
this.writeValue('');
|
||
|
this.onModelChange(this.value);
|
||
|
}
|
||
|
/**
|
||
|
* Callback to invoke when the mask is completed.
|
||
|
* @group Emits
|
||
|
*/
|
||
|
onComplete = new EventEmitter();
|
||
|
/**
|
||
|
* Callback to invoke when the component receives focus.
|
||
|
* @param {Event} event - Browser event.
|
||
|
* @group Emits
|
||
|
*/
|
||
|
onFocus = new EventEmitter();
|
||
|
/**
|
||
|
* Callback to invoke when the component loses focus.
|
||
|
* @param {Event} event - Browser event.
|
||
|
* @group Emits
|
||
|
*/
|
||
|
onBlur = new EventEmitter();
|
||
|
/**
|
||
|
* Callback to invoke on input.
|
||
|
* @param {Event} event - Browser event.
|
||
|
* @group Emits
|
||
|
*/
|
||
|
onInput = new EventEmitter();
|
||
|
/**
|
||
|
* Callback to invoke on input key press.
|
||
|
* @param {Event} event - Browser event.
|
||
|
* @group Emits
|
||
|
*/
|
||
|
onKeydown = new EventEmitter();
|
||
|
/**
|
||
|
* Callback to invoke when input field is cleared.
|
||
|
* @group Emits
|
||
|
*/
|
||
|
onClear = new EventEmitter();
|
||
|
inputViewChild;
|
||
|
templates;
|
||
|
clearIconTemplate;
|
||
|
value;
|
||
|
_mask;
|
||
|
onModelChange = () => { };
|
||
|
onModelTouched = () => { };
|
||
|
input;
|
||
|
filled;
|
||
|
defs;
|
||
|
tests;
|
||
|
partialPosition;
|
||
|
firstNonMaskPos;
|
||
|
lastRequiredNonMaskPos;
|
||
|
len;
|
||
|
oldVal;
|
||
|
buffer;
|
||
|
defaultBuffer;
|
||
|
focusText;
|
||
|
caretTimeoutId;
|
||
|
androidChrome = true;
|
||
|
focused;
|
||
|
_variant = 'outlined';
|
||
|
get inputClass() {
|
||
|
return {
|
||
|
'p-inputmask': true
|
||
|
};
|
||
|
}
|
||
|
constructor(document, platformId, el, cd, config) {
|
||
|
this.document = document;
|
||
|
this.platformId = platformId;
|
||
|
this.el = el;
|
||
|
this.cd = cd;
|
||
|
this.config = config;
|
||
|
}
|
||
|
ngOnInit() {
|
||
|
if (isPlatformBrowser(this.platformId)) {
|
||
|
let ua = navigator.userAgent;
|
||
|
this.androidChrome = /chrome/i.test(ua) && /android/i.test(ua);
|
||
|
}
|
||
|
this.initMask();
|
||
|
}
|
||
|
ngAfterContentInit() {
|
||
|
this.templates.forEach((item) => {
|
||
|
switch (item.getType()) {
|
||
|
case 'clearicon':
|
||
|
this.clearIconTemplate = item.template;
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
initMask() {
|
||
|
this.tests = [];
|
||
|
this.partialPosition = this.mask.length;
|
||
|
this.len = this.mask.length;
|
||
|
this.firstNonMaskPos = null;
|
||
|
this.defs = {
|
||
|
'9': '[0-9]',
|
||
|
a: this.characterPattern,
|
||
|
'*': `${this.characterPattern}|[0-9]`
|
||
|
};
|
||
|
let maskTokens = this.mask.split('');
|
||
|
for (let i = 0; i < maskTokens.length; i++) {
|
||
|
let c = maskTokens[i];
|
||
|
if (c == '?') {
|
||
|
this.len--;
|
||
|
this.partialPosition = i;
|
||
|
}
|
||
|
else if (this.defs[c]) {
|
||
|
this.tests.push(new RegExp(this.defs[c]));
|
||
|
if (this.firstNonMaskPos === null) {
|
||
|
this.firstNonMaskPos = this.tests.length - 1;
|
||
|
}
|
||
|
if (i < this.partialPosition) {
|
||
|
this.lastRequiredNonMaskPos = this.tests.length - 1;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
this.tests.push(null);
|
||
|
}
|
||
|
}
|
||
|
this.buffer = [];
|
||
|
for (let i = 0; i < maskTokens.length; i++) {
|
||
|
let c = maskTokens[i];
|
||
|
if (c != '?') {
|
||
|
if (this.defs[c])
|
||
|
this.buffer.push(this.getPlaceholder(i));
|
||
|
else
|
||
|
this.buffer.push(c);
|
||
|
}
|
||
|
}
|
||
|
this.defaultBuffer = this.buffer.join('');
|
||
|
}
|
||
|
writeValue(value) {
|
||
|
this.value = value;
|
||
|
if (this.inputViewChild && this.inputViewChild.nativeElement) {
|
||
|
if (this.value == undefined || this.value == null)
|
||
|
this.inputViewChild.nativeElement.value = '';
|
||
|
else
|
||
|
this.inputViewChild.nativeElement.value = this.value;
|
||
|
this.checkVal();
|
||
|
this.focusText = this.inputViewChild.nativeElement.value;
|
||
|
this.updateFilledState();
|
||
|
}
|
||
|
}
|
||
|
registerOnChange(fn) {
|
||
|
this.onModelChange = fn;
|
||
|
}
|
||
|
registerOnTouched(fn) {
|
||
|
this.onModelTouched = fn;
|
||
|
}
|
||
|
setDisabledState(val) {
|
||
|
this.disabled = val;
|
||
|
this.cd.markForCheck();
|
||
|
}
|
||
|
caret(first, last) {
|
||
|
let range, begin, end;
|
||
|
if (!this.inputViewChild?.nativeElement.offsetParent || this.inputViewChild.nativeElement !== this.inputViewChild.nativeElement.ownerDocument.activeElement) {
|
||
|
return;
|
||
|
}
|
||
|
if (typeof first == 'number') {
|
||
|
begin = first;
|
||
|
end = typeof last === 'number' ? last : begin;
|
||
|
if (this.inputViewChild.nativeElement.setSelectionRange) {
|
||
|
this.inputViewChild.nativeElement.setSelectionRange(begin, end);
|
||
|
}
|
||
|
else if (this.inputViewChild.nativeElement['createTextRange']) {
|
||
|
range = this.inputViewChild.nativeElement['createTextRange']();
|
||
|
range.collapse(true);
|
||
|
range.moveEnd('character', end);
|
||
|
range.moveStart('character', begin);
|
||
|
range.select();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (this.inputViewChild.nativeElement.setSelectionRange) {
|
||
|
begin = this.inputViewChild.nativeElement.selectionStart;
|
||
|
end = this.inputViewChild.nativeElement.selectionEnd;
|
||
|
}
|
||
|
else if (this.document && this.document['selection'].createRange) {
|
||
|
range = this.document.createRange();
|
||
|
begin = 0 - range.duplicate().moveStart('character', -100000);
|
||
|
end = begin + range.text.length;
|
||
|
}
|
||
|
return { begin: begin, end: end };
|
||
|
}
|
||
|
}
|
||
|
isCompleted() {
|
||
|
let completed;
|
||
|
for (let i = this.firstNonMaskPos; i <= this.lastRequiredNonMaskPos; i++) {
|
||
|
if (this.tests[i] && this.buffer[i] === this.getPlaceholder(i)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
getPlaceholder(i) {
|
||
|
if (i < this.slotChar.length) {
|
||
|
return this.slotChar.charAt(i);
|
||
|
}
|
||
|
return this.slotChar.charAt(0);
|
||
|
}
|
||
|
seekNext(pos) {
|
||
|
while (++pos < this.len && !this.tests[pos])
|
||
|
;
|
||
|
return pos;
|
||
|
}
|
||
|
seekPrev(pos) {
|
||
|
while (--pos >= 0 && !this.tests[pos])
|
||
|
;
|
||
|
return pos;
|
||
|
}
|
||
|
shiftL(begin, end) {
|
||
|
let i, j;
|
||
|
if (begin < 0) {
|
||
|
return;
|
||
|
}
|
||
|
for (i = begin, j = this.seekNext(end); i < this.len; i++) {
|
||
|
if (this.tests[i]) {
|
||
|
if (j < this.len && this.tests[i].test(this.buffer[j])) {
|
||
|
this.buffer[i] = this.buffer[j];
|
||
|
this.buffer[j] = this.getPlaceholder(j);
|
||
|
}
|
||
|
else {
|
||
|
break;
|
||
|
}
|
||
|
j = this.seekNext(j);
|
||
|
}
|
||
|
}
|
||
|
this.writeBuffer();
|
||
|
this.caret(Math.max(this.firstNonMaskPos, begin));
|
||
|
}
|
||
|
shiftR(pos) {
|
||
|
let i, c, j, t;
|
||
|
for (i = pos, c = this.getPlaceholder(pos); i < this.len; i++) {
|
||
|
if (this.tests[i]) {
|
||
|
j = this.seekNext(i);
|
||
|
t = this.buffer[i];
|
||
|
this.buffer[i] = c;
|
||
|
if (j < this.len && this.tests[j].test(t)) {
|
||
|
c = t;
|
||
|
}
|
||
|
else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
handleAndroidInput(e) {
|
||
|
var curVal = this.inputViewChild?.nativeElement.value;
|
||
|
var pos = this.caret();
|
||
|
if (this.oldVal && this.oldVal.length && this.oldVal.length > curVal.length) {
|
||
|
// a deletion or backspace happened
|
||
|
this.checkVal(true);
|
||
|
while (pos.begin > 0 && !this.tests[pos.begin - 1])
|
||
|
pos.begin--;
|
||
|
if (pos.begin === 0) {
|
||
|
while (pos.begin < this.firstNonMaskPos && !this.tests[pos.begin])
|
||
|
pos.begin++;
|
||
|
}
|
||
|
setTimeout(() => {
|
||
|
this.caret(pos.begin, pos.begin);
|
||
|
this.updateModel(e);
|
||
|
if (this.isCompleted()) {
|
||
|
this.onComplete.emit();
|
||
|
}
|
||
|
}, 0);
|
||
|
}
|
||
|
else {
|
||
|
this.checkVal(true);
|
||
|
while (pos.begin < this.len && !this.tests[pos.begin])
|
||
|
pos.begin++;
|
||
|
setTimeout(() => {
|
||
|
this.caret(pos.begin, pos.begin);
|
||
|
this.updateModel(e);
|
||
|
if (this.isCompleted()) {
|
||
|
this.onComplete.emit();
|
||
|
}
|
||
|
}, 0);
|
||
|
}
|
||
|
}
|
||
|
onInputBlur(e) {
|
||
|
this.focused = false;
|
||
|
this.onModelTouched();
|
||
|
if (!this.keepBuffer) {
|
||
|
this.checkVal();
|
||
|
}
|
||
|
this.updateFilledState();
|
||
|
this.onBlur.emit(e);
|
||
|
if (this.inputViewChild?.nativeElement.value != this.focusText || this.inputViewChild?.nativeElement.value != this.value) {
|
||
|
this.updateModel(e);
|
||
|
let event = this.document.createEvent('HTMLEvents');
|
||
|
event.initEvent('change', true, false);
|
||
|
this.inputViewChild?.nativeElement.dispatchEvent(event);
|
||
|
}
|
||
|
}
|
||
|
onInputKeydown(e) {
|
||
|
if (this.readonly) {
|
||
|
return;
|
||
|
}
|
||
|
let k = e.which || e.keyCode, pos, begin, end;
|
||
|
let iPhone;
|
||
|
if (isPlatformBrowser(this.platformId)) {
|
||
|
iPhone = /iphone/i.test(DomHandler.getUserAgent());
|
||
|
}
|
||
|
this.oldVal = this.inputViewChild?.nativeElement.value;
|
||
|
this.onKeydown.emit(e);
|
||
|
//backspace, delete, and escape get special treatment
|
||
|
if (k === 8 || k === 46 || (iPhone && k === 127)) {
|
||
|
pos = this.caret();
|
||
|
begin = pos.begin;
|
||
|
end = pos.end;
|
||
|
if (end - begin === 0) {
|
||
|
begin = k !== 46 ? this.seekPrev(begin) : (end = this.seekNext(begin - 1));
|
||
|
end = k === 46 ? this.seekNext(end) : end;
|
||
|
}
|
||
|
this.clearBuffer(begin, end);
|
||
|
if (this.keepBuffer) {
|
||
|
this.shiftL(begin, end - 2);
|
||
|
}
|
||
|
else {
|
||
|
this.shiftL(begin, end - 1);
|
||
|
}
|
||
|
this.updateModel(e);
|
||
|
this.onInput.emit(e);
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
else if (k === 13) {
|
||
|
// enter
|
||
|
this.onInputBlur(e);
|
||
|
this.updateModel(e);
|
||
|
}
|
||
|
else if (k === 27) {
|
||
|
// escape
|
||
|
this.inputViewChild.nativeElement.value = this.focusText;
|
||
|
this.caret(0, this.checkVal());
|
||
|
this.updateModel(e);
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
}
|
||
|
onKeyPress(e) {
|
||
|
if (this.readonly) {
|
||
|
return;
|
||
|
}
|
||
|
var k = e.which || e.keyCode, pos = this.caret(), p, c, next, completed;
|
||
|
if (e.ctrlKey || e.altKey || e.metaKey || k < 32 || (k > 34 && k < 41)) {
|
||
|
//Ignore
|
||
|
return;
|
||
|
}
|
||
|
else if (k && k !== 13) {
|
||
|
if (pos.end - pos.begin !== 0) {
|
||
|
this.clearBuffer(pos.begin, pos.end);
|
||
|
this.shiftL(pos.begin, pos.end - 1);
|
||
|
}
|
||
|
p = this.seekNext(pos.begin - 1);
|
||
|
if (p < this.len) {
|
||
|
c = String.fromCharCode(k);
|
||
|
if (this.tests[p].test(c)) {
|
||
|
this.shiftR(p);
|
||
|
this.buffer[p] = c;
|
||
|
this.writeBuffer();
|
||
|
next = this.seekNext(p);
|
||
|
if (DomHandler.isClient() && /android/i.test(DomHandler.getUserAgent())) {
|
||
|
let proxy = () => {
|
||
|
this.caret(next);
|
||
|
};
|
||
|
setTimeout(proxy, 0);
|
||
|
}
|
||
|
else {
|
||
|
this.caret(next);
|
||
|
}
|
||
|
if (pos.begin <= this.lastRequiredNonMaskPos) {
|
||
|
completed = this.isCompleted();
|
||
|
}
|
||
|
this.onInput.emit(e);
|
||
|
}
|
||
|
}
|
||
|
e.preventDefault();
|
||
|
}
|
||
|
this.updateModel(e);
|
||
|
this.updateFilledState();
|
||
|
if (completed) {
|
||
|
this.onComplete.emit();
|
||
|
}
|
||
|
}
|
||
|
clearBuffer(start, end) {
|
||
|
if (!this.keepBuffer) {
|
||
|
let i;
|
||
|
for (i = start; i < end && i < this.len; i++) {
|
||
|
if (this.tests[i]) {
|
||
|
this.buffer[i] = this.getPlaceholder(i);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
writeBuffer() {
|
||
|
this.inputViewChild.nativeElement.value = this.buffer.join('');
|
||
|
}
|
||
|
checkVal(allow) {
|
||
|
//try to place characters where they belong
|
||
|
let test = this.inputViewChild?.nativeElement.value, lastMatch = -1, i, c, pos;
|
||
|
for (i = 0, pos = 0; i < this.len; i++) {
|
||
|
if (this.tests[i]) {
|
||
|
this.buffer[i] = this.getPlaceholder(i);
|
||
|
while (pos++ < test.length) {
|
||
|
c = test.charAt(pos - 1);
|
||
|
if (this.tests[i].test(c)) {
|
||
|
if (!this.keepBuffer) {
|
||
|
this.buffer[i] = c;
|
||
|
}
|
||
|
lastMatch = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (pos > test.length) {
|
||
|
this.clearBuffer(i + 1, this.len);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (this.buffer[i] === test.charAt(pos)) {
|
||
|
pos++;
|
||
|
}
|
||
|
if (i < this.partialPosition) {
|
||
|
lastMatch = i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (allow) {
|
||
|
this.writeBuffer();
|
||
|
}
|
||
|
else if (lastMatch + 1 < this.partialPosition) {
|
||
|
if (this.autoClear || this.buffer.join('') === this.defaultBuffer) {
|
||
|
// Invalid value. Remove it and replace it with the
|
||
|
// mask, which is the default behavior.
|
||
|
if (this.inputViewChild?.nativeElement.value)
|
||
|
this.inputViewChild.nativeElement.value = '';
|
||
|
this.clearBuffer(0, this.len);
|
||
|
}
|
||
|
else {
|
||
|
// Invalid value, but we opt to show the value to the
|
||
|
// user and allow them to correct their mistake.
|
||
|
this.writeBuffer();
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
this.writeBuffer();
|
||
|
this.inputViewChild.nativeElement.value = this.inputViewChild?.nativeElement.value.substring(0, lastMatch + 1);
|
||
|
}
|
||
|
return (this.partialPosition ? i : this.firstNonMaskPos);
|
||
|
}
|
||
|
onInputFocus(event) {
|
||
|
if (this.readonly) {
|
||
|
return;
|
||
|
}
|
||
|
this.focused = true;
|
||
|
clearTimeout(this.caretTimeoutId);
|
||
|
let pos;
|
||
|
this.focusText = this.inputViewChild?.nativeElement.value;
|
||
|
pos = this.keepBuffer ? this.inputViewChild?.nativeElement.value.length : this.checkVal();
|
||
|
this.caretTimeoutId = setTimeout(() => {
|
||
|
if (this.inputViewChild?.nativeElement !== this.inputViewChild?.nativeElement.ownerDocument.activeElement) {
|
||
|
return;
|
||
|
}
|
||
|
this.writeBuffer();
|
||
|
if (pos == this.mask?.replace('?', '').length) {
|
||
|
this.caret(0, pos);
|
||
|
}
|
||
|
else {
|
||
|
this.caret(pos);
|
||
|
}
|
||
|
}, 10);
|
||
|
this.onFocus.emit(event);
|
||
|
}
|
||
|
onInputChange(event) {
|
||
|
if (this.androidChrome)
|
||
|
this.handleAndroidInput(event);
|
||
|
else
|
||
|
this.handleInputChange(event);
|
||
|
this.onInput.emit(event);
|
||
|
}
|
||
|
handleInputChange(event) {
|
||
|
if (this.readonly) {
|
||
|
return;
|
||
|
}
|
||
|
setTimeout(() => {
|
||
|
var pos = this.checkVal(true);
|
||
|
this.caret(pos);
|
||
|
this.updateModel(event);
|
||
|
if (this.isCompleted()) {
|
||
|
this.onComplete.emit();
|
||
|
}
|
||
|
}, 0);
|
||
|
}
|
||
|
getUnmaskedValue() {
|
||
|
let unmaskedBuffer = [];
|
||
|
for (let i = 0; i < this.buffer.length; i++) {
|
||
|
let c = this.buffer[i];
|
||
|
if (this.tests[i] && c != this.getPlaceholder(i)) {
|
||
|
unmaskedBuffer.push(c);
|
||
|
}
|
||
|
}
|
||
|
return unmaskedBuffer.join('');
|
||
|
}
|
||
|
updateModel(e) {
|
||
|
const updatedValue = this.unmask ? this.getUnmaskedValue() : e.target.value;
|
||
|
if (updatedValue !== null || updatedValue !== undefined) {
|
||
|
this.value = updatedValue;
|
||
|
this.onModelChange(this.value);
|
||
|
}
|
||
|
}
|
||
|
updateFilledState() {
|
||
|
this.filled = this.inputViewChild?.nativeElement && this.inputViewChild.nativeElement.value != '';
|
||
|
}
|
||
|
focus() {
|
||
|
this.inputViewChild?.nativeElement.focus();
|
||
|
}
|
||
|
clear() {
|
||
|
this.inputViewChild.nativeElement.value = '';
|
||
|
this.value = null;
|
||
|
this.onModelChange(this.value);
|
||
|
this.onClear.emit();
|
||
|
}
|
||
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: InputMask, deps: [{ token: DOCUMENT }, { token: PLATFORM_ID }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1.PrimeNGConfig }], target: i0.ɵɵFactoryTarget.Component });
|
||
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "17.3.7", type: InputMask, selector: "p-inputMask", inputs: { type: "type", slotChar: "slotChar", autoClear: ["autoClear", "autoClear", booleanAttribute], showClear: ["showClear", "showClear", booleanAttribute], style: "style", inputId: "inputId", styleClass: "styleClass", placeholder: "placeholder", size: ["size", "size", numberAttribute], maxlength: ["maxlength", "maxlength", numberAttribute], tabindex: "tabindex", title: "title", variant: "variant", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", ariaRequired: ["ariaRequired", "ariaRequired", booleanAttribute], disabled: ["disabled", "disabled", booleanAttribute], readonly: ["readonly", "readonly", booleanAttribute], unmask: ["unmask", "unmask", booleanAttribute], name: "name", required: ["required", "required", booleanAttribute], characterPattern: "characterPattern", autofocus: ["autofocus", "autofocus", booleanAttribute], autoFocus: ["autoFocus", "autoFocus", booleanAttribute], autocomplete: "autocomplete", keepBuffer: ["keepBuffer", "keepBuffer", booleanAttribute], mask: "mask" }, outputs: { onComplete: "onComplete", onFocus: "onFocus", onBlur: "onBlur", onInput: "onInput", onKeydown: "onKeydown", onClear: "onClear" }, host: { properties: { "class.p-inputwrapper-filled": "filled", "class.p-inputwrapper-focus": "focused", "class.p-inputmask-clearable": "showClear && !disabled" }, classAttribute: "p-element" }, providers: [INPUTMASK_VALUE_ACCESSOR], queries: [{ propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "inputViewChild", first: true, predicate: ["input"], descendants: true, static: true }], ngImport: i0, template: `
|
||
|
<input
|
||
|
#input
|
||
|
pInputText
|
||
|
[class]="styleClass"
|
||
|
[ngClass]="inputClass"
|
||
|
[attr.id]="inputId"
|
||
|
[attr.type]="type"
|
||
|
[attr.name]="name"
|
||
|
[ngStyle]="style"
|
||
|
[attr.placeholder]="placeholder"
|
||
|
[attr.title]="title"
|
||
|
[attr.size]="size"
|
||
|
[attr.autocomplete]="autocomplete"
|
||
|
[attr.maxlength]="maxlength"
|
||
|
[attr.tabindex]="tabindex"
|
||
|
[attr.aria-label]="ariaLabel"
|
||
|
[attr.aria-labelledBy]="ariaLabelledBy"
|
||
|
[attr.aria-required]="ariaRequired"
|
||
|
[disabled]="disabled"
|
||
|
[readonly]="readonly"
|
||
|
[attr.required]="required"
|
||
|
(focus)="onInputFocus($event)"
|
||
|
(blur)="onInputBlur($event)"
|
||
|
(keydown)="onInputKeydown($event)"
|
||
|
(keypress)="onKeyPress($event)"
|
||
|
pAutoFocus
|
||
|
[variant]="variant"
|
||
|
[autofocus]="autofocus"
|
||
|
(input)="onInputChange($event)"
|
||
|
(paste)="handleInputChange($event)"
|
||
|
[attr.data-pc-name]="'inputmask'"
|
||
|
[attr.data-pc-section]="'root'"
|
||
|
/>
|
||
|
<ng-container *ngIf="value != null && filled && showClear && !disabled">
|
||
|
<TimesIcon *ngIf="!clearIconTemplate" [styleClass]="'p-inputmask-clear-icon'" (click)="clear()" [attr.data-pc-section]="'clearIcon'" />
|
||
|
<span *ngIf="clearIconTemplate" class="p-inputmask-clear-icon" (click)="clear()" [attr.data-pc-section]="'clearIcon'">
|
||
|
<ng-template *ngTemplateOutlet="clearIconTemplate"></ng-template>
|
||
|
</span>
|
||
|
</ng-container>
|
||
|
`, isInline: true, styles: ["@layer primeng{.p-inputmask-clear-icon{position:absolute;top:50%;margin-top:-.5rem;cursor:pointer}.p-inputmask-clearable{position:relative}}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(() => i2.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgStyle), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i0.forwardRef(() => i3.InputText), selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: i0.forwardRef(() => i4.AutoFocus), selector: "[pAutoFocus]", inputs: ["autofocus"] }, { kind: "component", type: i0.forwardRef(() => TimesIcon), selector: "TimesIcon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
||
|
}
|
||
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: InputMask, decorators: [{
|
||
|
type: Component,
|
||
|
args: [{ selector: 'p-inputMask', template: `
|
||
|
<input
|
||
|
#input
|
||
|
pInputText
|
||
|
[class]="styleClass"
|
||
|
[ngClass]="inputClass"
|
||
|
[attr.id]="inputId"
|
||
|
[attr.type]="type"
|
||
|
[attr.name]="name"
|
||
|
[ngStyle]="style"
|
||
|
[attr.placeholder]="placeholder"
|
||
|
[attr.title]="title"
|
||
|
[attr.size]="size"
|
||
|
[attr.autocomplete]="autocomplete"
|
||
|
[attr.maxlength]="maxlength"
|
||
|
[attr.tabindex]="tabindex"
|
||
|
[attr.aria-label]="ariaLabel"
|
||
|
[attr.aria-labelledBy]="ariaLabelledBy"
|
||
|
[attr.aria-required]="ariaRequired"
|
||
|
[disabled]="disabled"
|
||
|
[readonly]="readonly"
|
||
|
[attr.required]="required"
|
||
|
(focus)="onInputFocus($event)"
|
||
|
(blur)="onInputBlur($event)"
|
||
|
(keydown)="onInputKeydown($event)"
|
||
|
(keypress)="onKeyPress($event)"
|
||
|
pAutoFocus
|
||
|
[variant]="variant"
|
||
|
[autofocus]="autofocus"
|
||
|
(input)="onInputChange($event)"
|
||
|
(paste)="handleInputChange($event)"
|
||
|
[attr.data-pc-name]="'inputmask'"
|
||
|
[attr.data-pc-section]="'root'"
|
||
|
/>
|
||
|
<ng-container *ngIf="value != null && filled && showClear && !disabled">
|
||
|
<TimesIcon *ngIf="!clearIconTemplate" [styleClass]="'p-inputmask-clear-icon'" (click)="clear()" [attr.data-pc-section]="'clearIcon'" />
|
||
|
<span *ngIf="clearIconTemplate" class="p-inputmask-clear-icon" (click)="clear()" [attr.data-pc-section]="'clearIcon'">
|
||
|
<ng-template *ngTemplateOutlet="clearIconTemplate"></ng-template>
|
||
|
</span>
|
||
|
</ng-container>
|
||
|
`, host: {
|
||
|
class: 'p-element',
|
||
|
'[class.p-inputwrapper-filled]': 'filled',
|
||
|
'[class.p-inputwrapper-focus]': 'focused',
|
||
|
'[class.p-inputmask-clearable]': 'showClear && !disabled'
|
||
|
}, providers: [INPUTMASK_VALUE_ACCESSOR], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, styles: ["@layer primeng{.p-inputmask-clear-icon{position:absolute;top:50%;margin-top:-.5rem;cursor:pointer}.p-inputmask-clearable{position:relative}}\n"] }]
|
||
|
}], ctorParameters: () => [{ type: Document, decorators: [{
|
||
|
type: Inject,
|
||
|
args: [DOCUMENT]
|
||
|
}] }, { type: undefined, decorators: [{
|
||
|
type: Inject,
|
||
|
args: [PLATFORM_ID]
|
||
|
}] }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1.PrimeNGConfig }], propDecorators: { type: [{
|
||
|
type: Input
|
||
|
}], slotChar: [{
|
||
|
type: Input
|
||
|
}], autoClear: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], showClear: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], style: [{
|
||
|
type: Input
|
||
|
}], inputId: [{
|
||
|
type: Input
|
||
|
}], styleClass: [{
|
||
|
type: Input
|
||
|
}], placeholder: [{
|
||
|
type: Input
|
||
|
}], size: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: numberAttribute }]
|
||
|
}], maxlength: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: numberAttribute }]
|
||
|
}], tabindex: [{
|
||
|
type: Input
|
||
|
}], title: [{
|
||
|
type: Input
|
||
|
}], variant: [{
|
||
|
type: Input
|
||
|
}], ariaLabel: [{
|
||
|
type: Input
|
||
|
}], ariaLabelledBy: [{
|
||
|
type: Input
|
||
|
}], ariaRequired: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], disabled: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], readonly: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], unmask: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], name: [{
|
||
|
type: Input
|
||
|
}], required: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], characterPattern: [{
|
||
|
type: Input
|
||
|
}], autofocus: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], autoFocus: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], autocomplete: [{
|
||
|
type: Input
|
||
|
}], keepBuffer: [{
|
||
|
type: Input,
|
||
|
args: [{ transform: booleanAttribute }]
|
||
|
}], mask: [{
|
||
|
type: Input
|
||
|
}], onComplete: [{
|
||
|
type: Output
|
||
|
}], onFocus: [{
|
||
|
type: Output
|
||
|
}], onBlur: [{
|
||
|
type: Output
|
||
|
}], onInput: [{
|
||
|
type: Output
|
||
|
}], onKeydown: [{
|
||
|
type: Output
|
||
|
}], onClear: [{
|
||
|
type: Output
|
||
|
}], inputViewChild: [{
|
||
|
type: ViewChild,
|
||
|
args: ['input', { static: true }]
|
||
|
}], templates: [{
|
||
|
type: ContentChildren,
|
||
|
args: [PrimeTemplate]
|
||
|
}] } });
|
||
|
export class InputMaskModule {
|
||
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: InputMaskModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
||
|
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.7", ngImport: i0, type: InputMaskModule, declarations: [InputMask], imports: [CommonModule, InputTextModule, AutoFocusModule, TimesIcon], exports: [InputMask, SharedModule] });
|
||
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: InputMaskModule, imports: [CommonModule, InputTextModule, AutoFocusModule, TimesIcon, SharedModule] });
|
||
|
}
|
||
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: InputMaskModule, decorators: [{
|
||
|
type: NgModule,
|
||
|
args: [{
|
||
|
imports: [CommonModule, InputTextModule, AutoFocusModule, TimesIcon],
|
||
|
exports: [InputMask, SharedModule],
|
||
|
declarations: [InputMask]
|
||
|
}]
|
||
|
}] });
|
||
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXRtYXNrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcC9jb21wb25lbnRzL2lucHV0bWFzay9pbnB1dG1hc2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBMEJFO0FBQ0YsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RSxPQUFPLEVBQ0gsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxlQUFlLEVBRWYsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsUUFBUSxFQUVSLE1BQU0sRUFDTixXQUFXLEVBR1gsU0FBUyxFQUNULGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsVUFBVSxFQUNWLGVBQWUsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBaUIsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7QUFJcEQsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQVE7SUFDekMsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQztJQUN4QyxLQUFLLEVBQUUsSUFBSTtDQUNkLENBQUM7QUFDRjs7O0dBR0c7QUF1REgsTUFBTSxPQUFPLFNBQVM7SUE0T29CO0lBQWlEO0lBQXdCO0lBQXVCO0lBQThCO0lBM09w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
|