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