From f50bc5907ffa928d47c3112df9bb8580df964c0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Merve=20=C3=96z=C3=A7if=C3=A7i?= Date: Tue, 2 Jan 2018 17:30:20 +0300 Subject: [PATCH] Fixed #265 --- src/App.js | 5 +- src/components/inputtext/InputText.js | 16 ++- src/components/keyfilter/KeyFilter.js | 89 ++++++++++++ src/components/utils/DomHandler.js | 35 +++++ src/showcase/keyfilter/KeyFilterDemo.js | 175 ++++++++++++++++++++++++ 5 files changed, 316 insertions(+), 4 deletions(-) create mode 100644 src/components/keyfilter/KeyFilter.js create mode 100644 src/showcase/keyfilter/KeyFilterDemo.js diff --git a/src/App.js b/src/App.js index 5c98f7a45e..b06644997c 100644 --- a/src/App.js +++ b/src/App.js @@ -105,7 +105,8 @@ import { TooltipDemo } from "./showcase/tooltip/TooltipDemo"; import { MenuModelDemo } from "./showcase/menumodel/MenuModelDemo"; import { SidebarDemo } from "./showcase/sidebar/SidebarDemo"; import { ProgressSpinnerDemo } from "./showcase/progressspinner/ProgressSpinnerDemo"; -import {CardDemo} from "./showcase/card/CardDemo"; +import { CardDemo } from "./showcase/card/CardDemo"; +import { KeyFilterDemo } from "./showcase/keyfilter/KeyFilterDemo"; class AppMenu extends Component { @@ -162,6 +163,7 @@ class AppMenu extends Component { ● Spinner ● TriState ● ToggleButton + ● KeyFilter @@ -527,6 +529,7 @@ class App extends Component { +
Released under the MIT License, Copyright © 2017 PrimeTek diff --git a/src/components/inputtext/InputText.js b/src/components/inputtext/InputText.js index b3e7254800..328f69e9af 100644 --- a/src/components/inputtext/InputText.js +++ b/src/components/inputtext/InputText.js @@ -1,20 +1,30 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; +import KeyFilter from "../keyfilter/KeyFilter"; export class InputText extends Component { static defaultProps = { - onInput: null + onInput: null, + keyfilter: null }; static propTypes = { - onInput: PropTypes.func + onInput: PropTypes.func, + keyfilter: PropTypes.any }; constructor(props) { super(props); this.onInput = this.onInput.bind(this); + this.onKeyPress = this.onKeyPress.bind(this); + } + + onKeyPress(event) { + if(this.props.keyfilter) { + KeyFilter.onKeyPress(event,this.props.keyfilter) + } } onInput(e) { @@ -52,6 +62,6 @@ export class InputText extends Component { let inputProps = Object.assign({}, this.props); delete inputProps.onInput; - return this.inputEl = el} {...inputProps} className={className} onInput={this.onInput}/>; + return this.inputEl = el} {...inputProps} className={className} onInput={this.onInput} onKeyPress={this.onKeyPress}/>; } } \ No newline at end of file diff --git a/src/components/keyfilter/KeyFilter.js b/src/components/keyfilter/KeyFilter.js new file mode 100644 index 0000000000..dae0b250d2 --- /dev/null +++ b/src/components/keyfilter/KeyFilter.js @@ -0,0 +1,89 @@ +import DomHandler from '../utils/DomHandler'; + +export default class KeyFilter { + /* eslint-disable */ + static DEFAULT_MASKS = { + 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 + }; + /* eslint-enable */ + + static KEYS = { + TAB: 9, + RETURN: 13, + ESC: 27, + BACKSPACE: 8, + DELETE: 46 + }; + + static SAFARI_KEYS = { + 63234: 37, // left + 63235: 39, // right + 63232: 38, // up + 63233: 40, // down + 63276: 33, // page up + 63277: 34, // page down + 63272: 46, // delete + 63273: 36, // home + 63275: 35 // end + }; + + static isNavKeyPress(e) { + let k = e.keyCode; + k = DomHandler.getBrowser().safari ? (KeyFilter.SAFARI_KEYS[k] || k) : k; + + return (k >= 33 && k <= 40) || k === KeyFilter.KEYS.RETURN || k === KeyFilter.KEYS.TAB || k === KeyFilter.KEYS.ESC; + } + + static isSpecialKey(e) { + let k = e.keyCode; + + return k === 9 || k === 13 || k === 27 || k === 16 || k === 17 ||(k >= 18 && k <= 20) || + (DomHandler.getBrowser().opera && !e.shiftKey && (k === 8 || (k >= 33 && k <= 35) || (k >= 36 && k <= 39) || (k >= 44 && k <= 45))); + } + + + static getKey(e) { + let k = e.keyCode || e.charCode; + return DomHandler.getBrowser().safari ? (KeyFilter.SAFARI_KEYS[k] || k) : k; + } + + static getCharCode(e) { + return e.charCode || e.keyCode || e.which; + } + + static onKeyPress(e,keyfilter) { + this.regex = KeyFilter.DEFAULT_MASKS[keyfilter]? KeyFilter.DEFAULT_MASKS[keyfilter] : keyfilter; + let browser = DomHandler.getBrowser(); + + if (e.ctrlKey || e.altKey) { + return; + } + + let k = this.getKey(e); + if (browser.mozilla && (this.isNavKeyPress(e) || k === KeyFilter.KEYS.BACKSPACE || (k === KeyFilter.KEYS.DELETE && e.charCode === 0))) { + return; + } + + let c = this.getCharCode(e); + let cc = String.fromCharCode(c); + let ok = true; + + if (browser.mozilla && (this.isSpecialKey(e) || !cc)) { + return; + } + + ok = this.regex.test(cc); + + if (!ok) { + e.preventDefault(); + } + } +} \ No newline at end of file diff --git a/src/components/utils/DomHandler.js b/src/components/utils/DomHandler.js index b664335774..37210e2625 100644 --- a/src/components/utils/DomHandler.js +++ b/src/components/utils/DomHandler.js @@ -326,4 +326,39 @@ export default class DomHandler { return scrollbarWidth; } + + static getBrowser() { + if(!this.browser) { + let matched = this.resolveUserAgent(); + this.browser = {}; + + if (matched.browser) { + this.browser[matched.browser] = true; + this.browser['version'] = matched.version; + } + + if (this.browser['chrome']) { + this.browser['webkit'] = true; + } else if (this.browser['webkit']) { + this.browser['safari'] = true; + } + } + + return this.browser; + } + + static resolveUserAgent() { + let ua = navigator.userAgent.toLowerCase(); + let match = /(chrome)[ ]([\w.]+)/.exec(ua) || + /(webkit)[ ]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ ]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + (ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua)) || + []; + + return { + browser: match[1] || "", + version: match[2] || "0" + }; + } } \ No newline at end of file diff --git a/src/showcase/keyfilter/KeyFilterDemo.js b/src/showcase/keyfilter/KeyFilterDemo.js new file mode 100644 index 0000000000..136e591e29 --- /dev/null +++ b/src/showcase/keyfilter/KeyFilterDemo.js @@ -0,0 +1,175 @@ +import React, {Component} from 'react'; +import {InputText} from '../../components/inputtext/InputText'; +import {TabView,TabPanel} from '../../components/tabview/TabView'; +import {CodeHighlight} from '../codehighlight/CodeHighlight'; + +export class KeyFilterDemo extends Component { + + render() { + return ( +
+
+
+

KeyFilter

+

KeyFilter directive restricts user input based on a regular expression.

+
+
+ +
+

Filtering

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ *!]+$/} placeholder="Block # < > * !"/> +
+
+ +
+
+
+ + +
+ ) + } +} + +class KeyFilterDoc extends Component { + + shouldComponentUpdate(){ + return false; + } + + render() { + return ( +
+ + +

Import

+ + {` +import {InputText} from 'primereact/components/inputtext/InputText'; + +`} + + +

Getting Started

+

KeyFilter is applied to an input text element using keyfilter attribute whose value is either a built-in regular expression name or a custom one. Following input only accepts integers.

+ + + {` + + +`} + + +

Built-in Filters

+

Commonly used cases have their own built-in shortcuts.

+
    +
  • pint: Positive integers
  • +
  • int: Integers
  • +
  • pnum: Positive numbers
  • +
  • num: Numbers
  • +
  • hex: Hexadecimal
  • +
  • email: Email
  • +
  • alpha: Alphabetic
  • +
  • alphanum: Alphanumeric
  • +
+ +

Custom Filter

+

A custom filter is provided by binding a regular expression, here is an example that blocks special characters

+ + {` +*!]+$/}/> + +`} + + +

Styling

+

This directive does not apply any styling.

+ +

Dependencies

+

None.

+
+ + + + + View on GitHub + + + {` +import React, {Component} from 'react'; +import {InputText} from '../../components/inputtext/InputText'; + +export class KeyFilterDemo extends Component { + + render() { + return ( +
+
+
+

KeyFilter

+

KeyFilter directive restricts user input based on a regular expression.

+
+
+ +
+

Filtering

+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ *!]+$/} placeholder="Block # < > * !"/> +
+
+ +
+
+
+
+ ) + } +} + +`} +
+
+
+
+ ) + } +}