Skip to content

Commit

Permalink
Fixed #265
Browse files Browse the repository at this point in the history
  • Loading branch information
Merve7 committed Jan 2, 2018
1 parent 47bfa9a commit f50bc59
Show file tree
Hide file tree
Showing 5 changed files with 316 additions and 4 deletions.
5 changes: 4 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -162,6 +163,7 @@ class AppMenu extends Component {
<Link to="/spinner">&#9679; Spinner</Link>
<Link to="/tristatecheckbox">&#9679; TriState</Link>
<Link to="/togglebutton">&#9679; ToggleButton</Link>
<Link to="/keyfilter">&#9679; KeyFilter</Link>
</div>
</div>

Expand Down Expand Up @@ -527,6 +529,7 @@ class App extends Component {
<Route path="/progressspinner" component={ProgressSpinnerDemo} />
<Route path="/scrollpanel" component={ScrollPanelDemo} />
<Route path="/card" component={CardDemo}/>
<Route path="/keyfilter" component={KeyFilterDemo}/>

<div className="content-section layout-footer clearfix">
<span>Released under the MIT License, Copyright © 2017 PrimeTek</span>
Expand Down
16 changes: 13 additions & 3 deletions src/components/inputtext/InputText.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -52,6 +62,6 @@ export class InputText extends Component {
let inputProps = Object.assign({}, this.props);
delete inputProps.onInput;

return <input ref={(el) => this.inputEl = el} {...inputProps} className={className} onInput={this.onInput}/>;
return <input ref={(el) => this.inputEl = el} {...inputProps} className={className} onInput={this.onInput} onKeyPress={this.onKeyPress}/>;
}
}
89 changes: 89 additions & 0 deletions src/components/keyfilter/KeyFilter.js
Original file line number Diff line number Diff line change
@@ -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();
}
}
}
35 changes: 35 additions & 0 deletions src/components/utils/DomHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"
};
}
}
175 changes: 175 additions & 0 deletions src/showcase/keyfilter/KeyFilterDemo.js
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<div className="content-section introduction">
<div className="feature-intro">
<h1>KeyFilter</h1>
<p>KeyFilter directive restricts user input based on a regular expression.</p>
</div>
</div>

<div className="content-section implementation">
<h3 className="first">Filtering</h3>
<div className="ui-g ui-fluid">
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="int" placeholder="Integers"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="num" placeholder="Numbers"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="money" placeholder="Money"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="hex" placeholder="Hex"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="alpha" placeholder="Alphabetic"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="alphanum" placeholder="Alphanumberic"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter={/^[^#<>*!]+$/} placeholder="Block # < > * !"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter={/[^\s]/} placeholder="Block space key"/>
</div>
</div>
</div>

<KeyFilterDoc />
</div>
)
}
}

class KeyFilterDoc extends Component {

shouldComponentUpdate(){
return false;
}

render() {
return (
<div className="content-section source">
<TabView>
<TabPanel header="Documentation">
<h3>Import</h3>
<CodeHighlight className="javascript">
{`
import {InputText} from 'primereact/components/inputtext/InputText';
`}
</CodeHighlight>

<h3>Getting Started</h3>
<p>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.</p>

<CodeHighlight className="html">
{`
<InputText keyfilter="int"/>
`}
</CodeHighlight>

<h3>Built-in Filters</h3>
<p>Commonly used cases have their own built-in shortcuts.</p>
<ul>
<li>pint: Positive integers</li>
<li>int: Integers</li>
<li>pnum: Positive numbers</li>
<li>num: Numbers</li>
<li>hex: Hexadecimal</li>
<li>email: Email</li>
<li>alpha: Alphabetic</li>
<li>alphanum: Alphanumeric</li>
</ul>

<h3>Custom Filter</h3>
<p>A custom filter is provided by binding a regular expression, here is an example that blocks special characters</p>
<CodeHighlight className="html">
{`
<InputText keyfilter={/^[^#<>*!]+$/}/>
`}
</CodeHighlight>

<h3>Styling</h3>
<p>This directive does not apply any styling.</p>

<h3>Dependencies</h3>
<p>None.</p>
</TabPanel>

<TabPanel header="Source">
<a href="https://github.com/primefaces/primereact/tree/master/src/showcase/inputtext" className="btn-viewsource" target="_blank" rel="noopener noreferrer">
<i className="fa fa-github"></i>
<span>View on GitHub</span>
</a>
<CodeHighlight className="javascript">
{`
import React, {Component} from 'react';
import {InputText} from '../../components/inputtext/InputText';
export class KeyFilterDemo extends Component {
render() {
return (
<div>
<div className="content-section introduction">
<div className="feature-intro">
<h1>KeyFilter</h1>
<p>KeyFilter directive restricts user input based on a regular expression.</p>
</div>
</div>
<div className="content-section implementation">
<h3 className="first">Filtering</h3>
<div className="ui-g ui-fluid">
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="int" placeholder="Integers"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="num" placeholder="Numbers"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="money" placeholder="Money"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="hex" placeholder="Hex"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="alpha" placeholder="Alphabetic"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter="alphanum" placeholder="Alphanumberic"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter={/^[^#<>*!]+$/} placeholder="Block # < > * !"/>
</div>
<div className="ui-g-12 ui-md-4">
<InputText keyfilter={/[^\\s]/} placeholder="Block space key"/>
</div>
</div>
</div>
</div>
)
}
}
`}
</CodeHighlight>
</TabPanel>
</TabView>
</div>
)
}
}

0 comments on commit f50bc59

Please sign in to comment.