Fixed #6503 - New KeyFilter directive
parent
21ae03bfce
commit
b88a144979
|
@ -0,0 +1,8 @@
|
||||||
|
import BaseDirective from '@primevue/core/basedirective';
|
||||||
|
import KeyFilterStyle from 'primevue/keyfilter/style';
|
||||||
|
|
||||||
|
const BaseKeyFilter = BaseDirective.extend({
|
||||||
|
style: KeyFilterStyle
|
||||||
|
});
|
||||||
|
|
||||||
|
export default BaseKeyFilter;
|
|
@ -0,0 +1,153 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* KeyFilter is a built-in feature of InputText to restrict user input based on a regular expression.
|
||||||
|
*
|
||||||
|
* [Live Demo](https://primevue.org/keyfilter)
|
||||||
|
*
|
||||||
|
* @module keyfilter
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import type { DesignToken, PassThrough } from '@primevue/core';
|
||||||
|
import type { DirectiveHooks } from '@primevue/core/basedirective';
|
||||||
|
import type { PassThroughOptions } from 'primevue/passthrough';
|
||||||
|
import { DirectiveBinding, ObjectDirective } from 'vue';
|
||||||
|
|
||||||
|
export declare type KeyFilterDirectivePassThroughOptionType = KeyFilterDirectivePassThroughAttributes | null | undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines options of KeyFilter.
|
||||||
|
*/
|
||||||
|
export interface KeyFilterOptions {
|
||||||
|
/**
|
||||||
|
* Sets the pattern for key filtering.
|
||||||
|
* @defaultValue null
|
||||||
|
*/
|
||||||
|
pattern?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* When enabled, instead of blocking keys, input is validated internally to test against the regular expression.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
validateOnly?: boolean;
|
||||||
|
/**
|
||||||
|
* It generates scoped CSS variables using design tokens for the component.
|
||||||
|
*/
|
||||||
|
dt?: DesignToken<any>;
|
||||||
|
/**
|
||||||
|
* Used to pass attributes to DOM elements inside the component.
|
||||||
|
* @type {KeyFilterDirectivePassThroughOptions}
|
||||||
|
*/
|
||||||
|
pt?: PassThrough<KeyFilterDirectivePassThroughOptions>;
|
||||||
|
/**
|
||||||
|
* Used to configure passthrough(pt) options of the component.
|
||||||
|
* @type {PassThroughOptions}
|
||||||
|
*/
|
||||||
|
ptOptions?: PassThroughOptions;
|
||||||
|
/**
|
||||||
|
* When enabled, it removes component related styles in the core.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
unstyled?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom passthrough(pt) options.
|
||||||
|
* @see {@link KeyFilterOptions.pt}
|
||||||
|
*/
|
||||||
|
export interface KeyFilterDirectivePassThroughOptions {
|
||||||
|
/**
|
||||||
|
* Used to pass attributes to the root's DOM element.
|
||||||
|
*/
|
||||||
|
root?: KeyFilterDirectivePassThroughOptionType;
|
||||||
|
/**
|
||||||
|
* Used to manage all lifecycle hooks.
|
||||||
|
* @see {@link BaseDirective.DirectiveHooks}
|
||||||
|
*/
|
||||||
|
hooks?: DirectiveHooks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom passthrough attributes for each DOM elements
|
||||||
|
*/
|
||||||
|
export interface KeyFilterDirectivePassThroughAttributes {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines modifiers of KeyFilter directive.
|
||||||
|
*/
|
||||||
|
export interface KeyFilterModifiers {
|
||||||
|
/**
|
||||||
|
* Positive integer pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
pint?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Integer pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
int?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Positive number pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
pnum?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Money pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
money?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Number pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
num?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Hexadecimal pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
hex?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Email pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
email?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Alphabetic pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
alpha?: RegExp | undefined;
|
||||||
|
/**
|
||||||
|
* Alphanumeric pattern for KeyFilter directive.
|
||||||
|
* @defaultValue false
|
||||||
|
*/
|
||||||
|
alphanum?: RegExp | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binding of KeyFilter directive.
|
||||||
|
*/
|
||||||
|
export interface KeyFilterDirectiveBinding extends Omit<DirectiveBinding, 'modifiers' | 'value'> {
|
||||||
|
/**
|
||||||
|
* Value of the KeyFilter.
|
||||||
|
*/
|
||||||
|
value?: string | KeyFilterOptions | undefined;
|
||||||
|
/**
|
||||||
|
* Modifiers of the KeyFilter.
|
||||||
|
* @type {KeyFilterModifiers}
|
||||||
|
*/
|
||||||
|
modifiers?: KeyFilterModifiers | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **PrimeVue - KeyFilter**
|
||||||
|
*
|
||||||
|
* _KeyFilter is a built-in feature of InputText to restrict user input based on a regular expression._
|
||||||
|
*
|
||||||
|
* [Live Demo](https://www.primevue.org/keyfilter/)
|
||||||
|
* --- ---
|
||||||
|
* ![PrimeVue](https://primefaces.org/cdn/primevue/images/logo-100.png)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
declare const KeyFilter: ObjectDirective;
|
||||||
|
|
||||||
|
export default KeyFilter;
|
|
@ -0,0 +1,128 @@
|
||||||
|
import { isAttributeEquals } from '@primeuix/utils/dom';
|
||||||
|
import BaseKeyFilter from './BaseKeyFilter';
|
||||||
|
|
||||||
|
const KeyFilter = BaseKeyFilter.extend('keyfilter', {
|
||||||
|
beforeMount(el, options) {
|
||||||
|
let target = this.getTarget(el);
|
||||||
|
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
target.$_pkeyfilterModifier = this.getModifiers(options);
|
||||||
|
|
||||||
|
if (typeof options.value) {
|
||||||
|
target.$_pkeyfilterPattern = options.value?.pattern || options.value;
|
||||||
|
target.$_pkeyfilterValidateOnly = options.value?.validateOnly || false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bindEvents(target);
|
||||||
|
|
||||||
|
target.setAttribute('data-pd-keyfilter', true);
|
||||||
|
},
|
||||||
|
updated(el, options) {
|
||||||
|
let target = this.getTarget(el);
|
||||||
|
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
target.$_pkeyfilterModifier = this.getModifiers(options);
|
||||||
|
this.unbindEvents(el, options);
|
||||||
|
|
||||||
|
if (typeof options.value) {
|
||||||
|
target.$_pkeyfilterPattern = options.value?.pattern || options.value;
|
||||||
|
target.$_pkeyfilterValidateOnly = options.value?.validateOnly || false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bindEvents(target);
|
||||||
|
},
|
||||||
|
unmounted(el, options) {
|
||||||
|
this.unbindEvents(el, options);
|
||||||
|
},
|
||||||
|
DEFAULT_PATTERNS: {
|
||||||
|
pint: /[\d]/,
|
||||||
|
int: /[\d\-]/,
|
||||||
|
pnum: /[\d\.]/,
|
||||||
|
money: /[\d\.\s,]/,
|
||||||
|
num: /[\d\-\.]/,
|
||||||
|
hex: /[0-9a-f]/i,
|
||||||
|
email: /[a-z0-9_\.\-@]/i,
|
||||||
|
alpha: /[a-z_]/i,
|
||||||
|
alphanum: /[a-z0-9_]/i
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getTarget(el) {
|
||||||
|
return isAttributeEquals(el, 'data-pc-name', 'inputtext') || isAttributeEquals(el, 'data-pc-name', 'textarea') ? el : null;
|
||||||
|
},
|
||||||
|
getModifiers(options) {
|
||||||
|
if (options.modifiers && Object.keys(options.modifiers).length) {
|
||||||
|
return Object.keys(options.modifiers)[Object.keys.length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
getRegex(target) {
|
||||||
|
return target.$_pkeyfilterPattern ? target.$_pkeyfilterPattern : target.$_pkeyfilterModifier ? this.DEFAULT_PATTERNS[target.$_pkeyfilterModifier] : /./;
|
||||||
|
},
|
||||||
|
bindEvents(el) {
|
||||||
|
el.$_keyfilterKeydownEvent = (event) => this.onKeydown(event, el);
|
||||||
|
el.$_keyfilterPasteEvent = (event) => this.onPaste(event, el);
|
||||||
|
|
||||||
|
el.addEventListener('keypress', el.$_keyfilterKeydownEvent);
|
||||||
|
el.addEventListener('paste', el.$_keyfilterPasteEvent);
|
||||||
|
},
|
||||||
|
unbindEvents(el) {
|
||||||
|
el.removeEventListener('keypress', el.$_keyfilterKeydownEvent);
|
||||||
|
el.removeEventListener('paste', el.$_keyfilterPasteEvent);
|
||||||
|
|
||||||
|
el.$_keyfilterKeydownEvent = null;
|
||||||
|
el.$_keyfilterPasteEvent = null;
|
||||||
|
},
|
||||||
|
onKeydown(event, target) {
|
||||||
|
if (event.ctrlKey || event.altKey || event.metaKey || event.key === 'Tab') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let regex = this.getRegex(target);
|
||||||
|
|
||||||
|
if (regex === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let testKey = `${event.key}`;
|
||||||
|
|
||||||
|
if (target.$_pkeyfilterValidateOnly) {
|
||||||
|
testKey = `${event.target.value}${event.key}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regex.test(testKey)) {
|
||||||
|
// runs before @update:modelValue emit
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onPaste(event, target) {
|
||||||
|
let regex = this.getRegex(target);
|
||||||
|
|
||||||
|
if (regex === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const clipboard = event.clipboardData.getData('text');
|
||||||
|
let testKey = '';
|
||||||
|
|
||||||
|
// loop over each letter pasted and if any fail prevent the paste
|
||||||
|
[...clipboard].forEach((c) => {
|
||||||
|
if (target.$_pkeyfilterValidateOnly) {
|
||||||
|
testKey += c;
|
||||||
|
} else {
|
||||||
|
testKey = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!regex.test(testKey)) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default KeyFilter;
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"main": "./KeyFilter.js",
|
||||||
|
"module": "./KeyFilter.js",
|
||||||
|
"types": "./KeyFilter.d.ts"
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* KeyFilter is a built-in feature of InputText to restrict user input based on a regular expression.
|
||||||
|
*
|
||||||
|
* [Live Demo](https://primevue.org/keyfilter)
|
||||||
|
*
|
||||||
|
* @module keyfilterstyle
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import type { BaseStyle } from '@primevue/core/base/style';
|
||||||
|
|
||||||
|
export enum KeyFilterClasses {}
|
||||||
|
|
||||||
|
export interface KeyFilterStyle extends BaseStyle {}
|
|
@ -0,0 +1,5 @@
|
||||||
|
import BaseStyle from '@primevue/core/base/style';
|
||||||
|
|
||||||
|
export default BaseStyle.extend({
|
||||||
|
name: 'keyfilter-directive'
|
||||||
|
});
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"main": "./KeyFilterStyle.js",
|
||||||
|
"module": "./KeyFilterStyle.js",
|
||||||
|
"types": "./KeyFilterStyle.d.ts",
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
Loading…
Reference in New Issue