Created
March 6, 2015 04:33
-
-
Save proclaim/a1e572767cd83e0195bf to your computer and use it in GitHub Desktop.
React Input Field [React Input Field] // source http://jsbin.com/qucoca
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="[React Input Field]"> | |
<script src="http://code.jquery.com/jquery.min.js"></script> | |
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" type="text/css" /> | |
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> | |
<script src="http://fb.me/react-with-addons-0.12.2.js"></script> | |
<meta charset="utf-8"> | |
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script> | |
<title>React Input Field</title> | |
</head> | |
<body> | |
<div id="app"></div> | |
<script id="jsbin-javascript"> | |
var InputField = React.createClass({displayName: 'InputField', | |
propTypes: { | |
type : React.PropTypes.oneOf(['default','withIcon']), | |
name : React.PropTypes.string.isRequired, // identifier for onChange event | |
label : React.PropTypes.string, // label to be displayed | |
value : React.PropTypes.string, // set value to input field | |
iconText : React.PropTypes.string, // text used when using type 2 | |
iconClassName : React.PropTypes.string, // icon class used when using type 2, if provided, will overwrite icon | |
placeholder : React.PropTypes.string, // place holder text | |
inputType : React.PropTypes.string, // text || password || number || range || email | |
inputSize : React.PropTypes.string, // (empty) || large || small | |
required : React.PropTypes.bool, // will have red border when input is empty | |
onChange : React.PropTypes.func.isRequired, // will return [ name (string), value(string), 3.isValidInput (bool) ] | |
min : React.PropTypes.number, // minimum for range input | |
max : React.PropTypes.number, // maxumum for range input | |
validationRegex : React.PropTypes.object // regular expression for validation | |
}, | |
getDefaultProps: function() { | |
return { | |
type : 'default', | |
name : 'input-field', | |
label : '', | |
icon : '', | |
iconClassName : '', | |
placeholder : '', | |
inputType : 'text', | |
inputSize : '', | |
required : false, | |
min : 0, | |
max : 100, | |
validationRegex : null | |
}; | |
}, | |
getInitialState: function() { | |
return { | |
isValidInput : true | |
}; | |
}, | |
_matchRequiredRule: function(value) { | |
return value !== ''; | |
}, | |
_matchEmailRule: function(email) { | |
// current email rule is [string]@[string] simple verification | |
return email.match(/\S+@\S+/) !== null; | |
}, | |
_handleFieldChange: function(event) { | |
var currentInputIsValid = true, | |
inputValue = event.target.value; | |
if(this.props.validationRegex !== null) { | |
currentInputIsValid = inputValue.match(this.props.validationRegex) !== null; | |
} | |
else { | |
switch(this.props.inputType) { | |
case 'email': | |
currentInputIsValid = this._matchEmailRule(event.target.value); | |
break; | |
case 'number': | |
// if user paste in data, strip all none numbers | |
event.target.value = event.target.value.replace(/\D/g,''); | |
break; | |
} | |
} | |
if(this.props.required && currentInputIsValid) { | |
currentInputIsValid = this._matchRequiredRule(inputValue); | |
} | |
this.setState({ | |
isValidInput: currentInputIsValid | |
}); | |
this.props.onChange(this.props.name, inputValue, currentInputIsValid); | |
}, | |
_handleFieldBlur: function(event) { | |
this._handleFieldChange(event); | |
}, | |
_handleKeyDown: function(event) { | |
// validation for number | |
if(this.props.inputType == 'number') { | |
// Allow: backspace, delete, tab, escape, enter and . | |
if ($.inArray(event.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 || | |
// Allow: Ctrl+A | |
(event.keyCode == 65 && (event.metaKey || event.ctrlKey)) || | |
// Allow paste (ctrl + V) | |
(event.keyCode == 86 && (event.metaKey || event.ctrlKey)) || | |
// Allow copy (Ctrl + C) | |
(event.keyCode == 67 && (event.metaKey || event.ctrlKey)) || | |
// Allow: home, end, left, right, down, up | |
(event.keyCode >= 35 && event.keyCode <= 40)) { | |
// let it happen, don't do anything | |
} | |
// check for number only | |
else if ((event.shiftKey || (event.keyCode < 48 || event.keyCode > 57)) && (event.keyCode < 96 || event.keyCode > 105)) { | |
event.preventDefault(); | |
} | |
} | |
}, | |
_renderDefault: function(inputType, fieldClass, inputClass) { | |
var labelHtml = ''; | |
if(this.props.label) { | |
labelHtml = React.createElement("label", {className: "control-label", htmlFor: this.props.name}, this.props.label); | |
} | |
return ( | |
React.createElement("div", {className: fieldClass}, | |
labelHtml, | |
React.createElement("input", { | |
id: this.props.name, | |
type: inputType, | |
value: this.props.value, | |
className: inputClass, | |
placeholder: this.props.placeholder, | |
onKeyDown: this._handleKeyDown, | |
onChange: this._handleFieldChange, | |
onBlur: this._handleFieldBlur, | |
min: this.props.min, | |
max: this.props.max}) | |
) | |
); | |
}, | |
_renderWithIcon: function(inputType, fieldClass, inputClass) { | |
var iconHtml = this.props.iconText, | |
labelHtml = '', | |
contentHtml; | |
if(this.props.iconClassName) { | |
iconHtml = React.createElement("i", {className: this.props.iconClassName}); | |
} | |
if(this.props.labelHtml) { | |
labelHtml = React.createElement("label", {className: "control-label", htmlFor: this.props.name}, this.props.label); | |
} | |
return ( | |
React.createElement("div", {className: fieldClass}, | |
labelHtml, | |
React.createElement("div", {className: "input-group"}, | |
React.createElement("span", {className: "input-group-addon"}, iconHtml), | |
React.createElement("input", { | |
id: this.props.name, | |
type: inputType, | |
value: this.props.value, | |
className: inputClass, | |
placeholder: this.props.placeholder, | |
onKeyUp: this._handleKeyDown, | |
onChange: this._handleFieldChange, | |
onBlur: this._handleFieldBlur}) | |
) | |
) | |
); | |
}, | |
render: function() { | |
var CX = React.addons.classSet, | |
contentHtml = '', | |
inputType = '', | |
fieldClass, | |
inputClass; | |
inputType = this.props.inputType == 'number' ? 'text' : this.props.inputType; | |
fieldClass = CX({ | |
'form-group' : true, | |
'has-error' : !this.state.isValidInput | |
}); | |
inputClass = CX({ | |
'form-control' : this.props.inputType != 'range', | |
'input-lg' : this.props.inputSize == 'large', | |
'input-sm' : this.props.inputSize == 'small' | |
}); | |
switch(this.props.type) | |
{ | |
case 'withIcon': | |
contentHtml = this._renderWithIcon(inputType, fieldClass, inputClass); | |
break; | |
default: | |
contentHtml = this._renderDefault(inputType, fieldClass, inputClass); | |
break; | |
} | |
/* jshint ignore:start */ | |
return ( | |
React.createElement("div", null, | |
contentHtml | |
) | |
); | |
/* jshint ignore:end */ | |
} | |
}); | |
Test = React.createClass({displayName: 'Test', | |
getInitialState: function() { | |
return { | |
source: '', | |
value: '', | |
isValid: true | |
}; | |
}, | |
_handleInputChange: function(source, value, isValid) { | |
this.setState({ | |
source: source, | |
value: value, | |
isValid: isValid | |
}) | |
}, | |
render: function() { | |
/* jshint ignore:start */ | |
return ( | |
React.createElement("div", null, | |
React.createElement("p", null, | |
"Source is: ", React.createElement("code", null, this.state.source), React.createElement("br", null), | |
"value is: ", React.createElement("code", null, this.state.value), React.createElement("br", null), | |
"isInputValid: ", React.createElement("code", null, this.state.isValid.toString()) | |
), | |
React.createElement("h4", null, "Type 1 showcase - regular input field"), | |
React.createElement(InputField, {name: "Regular", label: "[Regular]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "RegularRequired", label: "[RegularRequired]", onChange: this._handleInputChange, required: true}), | |
React.createElement(InputField, {name: "NumberOnly", inputType: "number", label: "[NumberOnly]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "Password", inputType: "password", label: "[Password]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "Email", inputType: "email", label: "[Email]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "CustomRegex", inputType: "text", label: "[CustomRegex] numbers only ex: /^\\d+$/", validationRegex: /^\d+$/, onChange: this._handleInputChange}), | |
React.createElement("hr", null), | |
React.createElement("h4", null, "Other Variation"), | |
React.createElement(InputField, {name: "RegularLarge", label: "[RegularLarge]", onChange: this._handleInputChange, inputSize: "large"}), | |
React.createElement(InputField, {name: "RegularLarge", label: "[RegularLarge]", onChange: this._handleInputChange, inputSize: "small"}), | |
React.createElement(InputField, {name: "Range", label: "[Range]", inputType: "range", onChange: this._handleInputChange, min: 0, max: 100}), | |
React.createElement(InputField, {name: "Placeholder", placeholder: "placeholder (no label)", onChange: this._handleInputChange}), | |
React.createElement("hr", null), | |
React.createElement("h4", null, "Type 2 showcase - input with icon"), | |
React.createElement(InputField, {type: "withIcon", name: "IconInputUsingText", iconText: "$", onChange: this._handleInputChange}), | |
React.createElement(InputField, {type: "withIcon", name: "IconInputUsingClass", iconClassName: "glyphicon glyphicon-search", onChange: this._handleInputChange}) | |
) | |
); | |
/* jshint ignore:end */ | |
} | |
}); | |
var regex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9]+$/gi; | |
var ExampleApp = React.createClass({displayName: 'ExampleApp', | |
render: function() { | |
return ( | |
/*jshint ignore:start */ | |
React.createElement("div", {className: "container"}, | |
React.createElement("h2", null, "Input Field Test Cases"), | |
React.createElement(Test, null) | |
) | |
/*jshint ignore:end */ | |
); | |
} | |
}); | |
React.render( | |
/*jshint ignore:start */ | |
React.createElement(ExampleApp, null), | |
/*jshint ignore:end */ | |
document.getElementById('app') | |
); | |
</script> | |
<script id="jsbin-source-html" type="text/html"><!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="[React Input Field]"> | |
<script src="//code.jquery.com/jquery.min.js"><\/script> | |
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" type="text/css" /> | |
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"><\/script> | |
<script src="//fb.me/react-with-addons-0.12.2.js"><\/script> | |
<meta charset="utf-8"> | |
<script src="//code.jquery.com/jquery-2.1.1.min.js"><\/script> | |
<title>React Input Field</title> | |
</head> | |
<body> | |
<div id="app"></div> | |
</body> | |
</html></script> | |
<script id="jsbin-source-javascript" type="text/javascript">var InputField = React.createClass({ | |
propTypes: { | |
type : React.PropTypes.oneOf(['default','withIcon']), | |
name : React.PropTypes.string.isRequired, // identifier for onChange event | |
label : React.PropTypes.string, // label to be displayed | |
value : React.PropTypes.string, // set value to input field | |
iconText : React.PropTypes.string, // text used when using type 2 | |
iconClassName : React.PropTypes.string, // icon class used when using type 2, if provided, will overwrite icon | |
placeholder : React.PropTypes.string, // place holder text | |
inputType : React.PropTypes.string, // text || password || number || range || email | |
inputSize : React.PropTypes.string, // (empty) || large || small | |
required : React.PropTypes.bool, // will have red border when input is empty | |
onChange : React.PropTypes.func.isRequired, // will return [ name (string), value(string), 3.isValidInput (bool) ] | |
min : React.PropTypes.number, // minimum for range input | |
max : React.PropTypes.number, // maxumum for range input | |
validationRegex : React.PropTypes.object // regular expression for validation | |
}, | |
getDefaultProps: function() { | |
return { | |
type : 'default', | |
name : 'input-field', | |
label : '', | |
icon : '', | |
iconClassName : '', | |
placeholder : '', | |
inputType : 'text', | |
inputSize : '', | |
required : false, | |
min : 0, | |
max : 100, | |
validationRegex : null | |
}; | |
}, | |
getInitialState: function() { | |
return { | |
isValidInput : true | |
}; | |
}, | |
_matchRequiredRule: function(value) { | |
return value !== ''; | |
}, | |
_matchEmailRule: function(email) { | |
// current email rule is [string]@[string] simple verification | |
return email.match(/\S+@\S+/) !== null; | |
}, | |
_handleFieldChange: function(event) { | |
var currentInputIsValid = true, | |
inputValue = event.target.value; | |
if(this.props.validationRegex !== null) { | |
currentInputIsValid = inputValue.match(this.props.validationRegex) !== null; | |
} | |
else { | |
switch(this.props.inputType) { | |
case 'email': | |
currentInputIsValid = this._matchEmailRule(event.target.value); | |
break; | |
case 'number': | |
// if user paste in data, strip all none numbers | |
event.target.value = event.target.value.replace(/\D/g,''); | |
break; | |
} | |
} | |
if(this.props.required && currentInputIsValid) { | |
currentInputIsValid = this._matchRequiredRule(inputValue); | |
} | |
this.setState({ | |
isValidInput: currentInputIsValid | |
}); | |
this.props.onChange(this.props.name, inputValue, currentInputIsValid); | |
}, | |
_handleFieldBlur: function(event) { | |
this._handleFieldChange(event); | |
}, | |
_handleKeyDown: function(event) { | |
// validation for number | |
if(this.props.inputType == 'number') { | |
// Allow: backspace, delete, tab, escape, enter and . | |
if ($.inArray(event.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 || | |
// Allow: Ctrl+A | |
(event.keyCode == 65 && (event.metaKey || event.ctrlKey)) || | |
// Allow paste (ctrl + V) | |
(event.keyCode == 86 && (event.metaKey || event.ctrlKey)) || | |
// Allow copy (Ctrl + C) | |
(event.keyCode == 67 && (event.metaKey || event.ctrlKey)) || | |
// Allow: home, end, left, right, down, up | |
(event.keyCode >= 35 && event.keyCode <= 40)) { | |
// let it happen, don't do anything | |
} | |
// check for number only | |
else if ((event.shiftKey || (event.keyCode < 48 || event.keyCode > 57)) && (event.keyCode < 96 || event.keyCode > 105)) { | |
event.preventDefault(); | |
} | |
} | |
}, | |
_renderDefault: function(inputType, fieldClass, inputClass) { | |
var labelHtml = ''; | |
if(this.props.label) { | |
labelHtml = <label className="control-label" htmlFor={this.props.name}>{this.props.label}</label>; | |
} | |
return ( | |
<div className={fieldClass}> | |
{labelHtml} | |
<input | |
id = {this.props.name} | |
type = {inputType} | |
value = {this.props.value} | |
className = {inputClass} | |
placeholder = {this.props.placeholder} | |
onKeyDown = {this._handleKeyDown} | |
onChange = {this._handleFieldChange} | |
onBlur = {this._handleFieldBlur} | |
min = {this.props.min} | |
max = {this.props.max} /> | |
</div> | |
); | |
}, | |
_renderWithIcon: function(inputType, fieldClass, inputClass) { | |
var iconHtml = this.props.iconText, | |
labelHtml = '', | |
contentHtml; | |
if(this.props.iconClassName) { | |
iconHtml = <i className={this.props.iconClassName}></i>; | |
} | |
if(this.props.labelHtml) { | |
labelHtml = <label className="control-label" htmlFor={this.props.name}>{this.props.label}</label>; | |
} | |
return ( | |
<div className={fieldClass}> | |
{labelHtml} | |
<div className="input-group"> | |
<span className="input-group-addon">{iconHtml}</span> | |
<input | |
id = {this.props.name} | |
type = {inputType} | |
value = {this.props.value} | |
className = {inputClass} | |
placeholder = {this.props.placeholder} | |
onKeyUp = {this._handleKeyDown} | |
onChange = {this._handleFieldChange} | |
onBlur = {this._handleFieldBlur} /> | |
</div> | |
</div> | |
); | |
}, | |
render: function() { | |
var CX = React.addons.classSet, | |
contentHtml = '', | |
inputType = '', | |
fieldClass, | |
inputClass; | |
inputType = this.props.inputType == 'number' ? 'text' : this.props.inputType; | |
fieldClass = CX({ | |
'form-group' : true, | |
'has-error' : !this.state.isValidInput | |
}); | |
inputClass = CX({ | |
'form-control' : this.props.inputType != 'range', | |
'input-lg' : this.props.inputSize == 'large', | |
'input-sm' : this.props.inputSize == 'small' | |
}); | |
switch(this.props.type) | |
{ | |
case 'withIcon': | |
contentHtml = this._renderWithIcon(inputType, fieldClass, inputClass); | |
break; | |
default: | |
contentHtml = this._renderDefault(inputType, fieldClass, inputClass); | |
break; | |
} | |
/* jshint ignore:start */ | |
return ( | |
<div> | |
{contentHtml} | |
</div> | |
); | |
/* jshint ignore:end */ | |
} | |
}); | |
Test = React.createClass({ | |
getInitialState: function() { | |
return { | |
source: '', | |
value: '', | |
isValid: true | |
}; | |
}, | |
_handleInputChange: function(source, value, isValid) { | |
this.setState({ | |
source: source, | |
value: value, | |
isValid: isValid | |
}) | |
}, | |
render: function() { | |
/* jshint ignore:start */ | |
return ( | |
<div> | |
<p> | |
Source is: <code>{this.state.source}</code><br/> | |
value is: <code>{this.state.value}</code><br/> | |
isInputValid: <code>{this.state.isValid.toString()}</code> | |
</p> | |
<h4>Type 1 showcase - regular input field</h4> | |
<InputField name="Regular" label="[Regular]" onChange={this._handleInputChange} /> | |
<InputField name="RegularRequired" label="[RegularRequired]" onChange={this._handleInputChange} required={true} /> | |
<InputField name="NumberOnly" inputType="number" label="[NumberOnly]" onChange={this._handleInputChange} /> | |
<InputField name="Password" inputType="password" label="[Password]" onChange={this._handleInputChange} /> | |
<InputField name="Email" inputType="email" label="[Email]" onChange={this._handleInputChange} /> | |
<InputField name="CustomRegex" inputType="text" label="[CustomRegex] numbers only ex: /^\d+$/" validationRegex={/^\d+$/} onChange={this._handleInputChange} /> | |
<hr /> | |
<h4>Other Variation</h4> | |
<InputField name="RegularLarge" label="[RegularLarge]" onChange={this._handleInputChange} inputSize="large" /> | |
<InputField name="RegularLarge" label="[RegularLarge]" onChange={this._handleInputChange} inputSize="small" /> | |
<InputField name="Range" label="[Range]" inputType="range" onChange={this._handleInputChange} min={0} max={100} /> | |
<InputField name="Placeholder" placeholder="placeholder (no label)" onChange={this._handleInputChange} /> | |
<hr /> | |
<h4>Type 2 showcase - input with icon</h4> | |
<InputField type="withIcon" name="IconInputUsingText" iconText="$" onChange={this._handleInputChange} /> | |
<InputField type="withIcon" name="IconInputUsingClass" iconClassName="glyphicon glyphicon-search" onChange={this._handleInputChange} /> | |
</div> | |
); | |
/* jshint ignore:end */ | |
} | |
}); | |
var regex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9]+$/gi; | |
var ExampleApp = React.createClass({ | |
render: function() { | |
return ( | |
/*jshint ignore:start */ | |
<div className="container"> | |
<h2>Input Field Test Cases</h2> | |
<Test /> | |
</div> | |
/*jshint ignore:end */ | |
); | |
} | |
}); | |
React.render( | |
/*jshint ignore:start */ | |
<ExampleApp />, | |
/*jshint ignore:end */ | |
document.getElementById('app') | |
);</script></body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var InputField = React.createClass({displayName: 'InputField', | |
propTypes: { | |
type : React.PropTypes.oneOf(['default','withIcon']), | |
name : React.PropTypes.string.isRequired, // identifier for onChange event | |
label : React.PropTypes.string, // label to be displayed | |
value : React.PropTypes.string, // set value to input field | |
iconText : React.PropTypes.string, // text used when using type 2 | |
iconClassName : React.PropTypes.string, // icon class used when using type 2, if provided, will overwrite icon | |
placeholder : React.PropTypes.string, // place holder text | |
inputType : React.PropTypes.string, // text || password || number || range || email | |
inputSize : React.PropTypes.string, // (empty) || large || small | |
required : React.PropTypes.bool, // will have red border when input is empty | |
onChange : React.PropTypes.func.isRequired, // will return [ name (string), value(string), 3.isValidInput (bool) ] | |
min : React.PropTypes.number, // minimum for range input | |
max : React.PropTypes.number, // maxumum for range input | |
validationRegex : React.PropTypes.object // regular expression for validation | |
}, | |
getDefaultProps: function() { | |
return { | |
type : 'default', | |
name : 'input-field', | |
label : '', | |
icon : '', | |
iconClassName : '', | |
placeholder : '', | |
inputType : 'text', | |
inputSize : '', | |
required : false, | |
min : 0, | |
max : 100, | |
validationRegex : null | |
}; | |
}, | |
getInitialState: function() { | |
return { | |
isValidInput : true | |
}; | |
}, | |
_matchRequiredRule: function(value) { | |
return value !== ''; | |
}, | |
_matchEmailRule: function(email) { | |
// current email rule is [string]@[string] simple verification | |
return email.match(/\S+@\S+/) !== null; | |
}, | |
_handleFieldChange: function(event) { | |
var currentInputIsValid = true, | |
inputValue = event.target.value; | |
if(this.props.validationRegex !== null) { | |
currentInputIsValid = inputValue.match(this.props.validationRegex) !== null; | |
} | |
else { | |
switch(this.props.inputType) { | |
case 'email': | |
currentInputIsValid = this._matchEmailRule(event.target.value); | |
break; | |
case 'number': | |
// if user paste in data, strip all none numbers | |
event.target.value = event.target.value.replace(/\D/g,''); | |
break; | |
} | |
} | |
if(this.props.required && currentInputIsValid) { | |
currentInputIsValid = this._matchRequiredRule(inputValue); | |
} | |
this.setState({ | |
isValidInput: currentInputIsValid | |
}); | |
this.props.onChange(this.props.name, inputValue, currentInputIsValid); | |
}, | |
_handleFieldBlur: function(event) { | |
this._handleFieldChange(event); | |
}, | |
_handleKeyDown: function(event) { | |
// validation for number | |
if(this.props.inputType == 'number') { | |
// Allow: backspace, delete, tab, escape, enter and . | |
if ($.inArray(event.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 || | |
// Allow: Ctrl+A | |
(event.keyCode == 65 && (event.metaKey || event.ctrlKey)) || | |
// Allow paste (ctrl + V) | |
(event.keyCode == 86 && (event.metaKey || event.ctrlKey)) || | |
// Allow copy (Ctrl + C) | |
(event.keyCode == 67 && (event.metaKey || event.ctrlKey)) || | |
// Allow: home, end, left, right, down, up | |
(event.keyCode >= 35 && event.keyCode <= 40)) { | |
// let it happen, don't do anything | |
} | |
// check for number only | |
else if ((event.shiftKey || (event.keyCode < 48 || event.keyCode > 57)) && (event.keyCode < 96 || event.keyCode > 105)) { | |
event.preventDefault(); | |
} | |
} | |
}, | |
_renderDefault: function(inputType, fieldClass, inputClass) { | |
var labelHtml = ''; | |
if(this.props.label) { | |
labelHtml = React.createElement("label", {className: "control-label", htmlFor: this.props.name}, this.props.label); | |
} | |
return ( | |
React.createElement("div", {className: fieldClass}, | |
labelHtml, | |
React.createElement("input", { | |
id: this.props.name, | |
type: inputType, | |
value: this.props.value, | |
className: inputClass, | |
placeholder: this.props.placeholder, | |
onKeyDown: this._handleKeyDown, | |
onChange: this._handleFieldChange, | |
onBlur: this._handleFieldBlur, | |
min: this.props.min, | |
max: this.props.max}) | |
) | |
); | |
}, | |
_renderWithIcon: function(inputType, fieldClass, inputClass) { | |
var iconHtml = this.props.iconText, | |
labelHtml = '', | |
contentHtml; | |
if(this.props.iconClassName) { | |
iconHtml = React.createElement("i", {className: this.props.iconClassName}); | |
} | |
if(this.props.labelHtml) { | |
labelHtml = React.createElement("label", {className: "control-label", htmlFor: this.props.name}, this.props.label); | |
} | |
return ( | |
React.createElement("div", {className: fieldClass}, | |
labelHtml, | |
React.createElement("div", {className: "input-group"}, | |
React.createElement("span", {className: "input-group-addon"}, iconHtml), | |
React.createElement("input", { | |
id: this.props.name, | |
type: inputType, | |
value: this.props.value, | |
className: inputClass, | |
placeholder: this.props.placeholder, | |
onKeyUp: this._handleKeyDown, | |
onChange: this._handleFieldChange, | |
onBlur: this._handleFieldBlur}) | |
) | |
) | |
); | |
}, | |
render: function() { | |
var CX = React.addons.classSet, | |
contentHtml = '', | |
inputType = '', | |
fieldClass, | |
inputClass; | |
inputType = this.props.inputType == 'number' ? 'text' : this.props.inputType; | |
fieldClass = CX({ | |
'form-group' : true, | |
'has-error' : !this.state.isValidInput | |
}); | |
inputClass = CX({ | |
'form-control' : this.props.inputType != 'range', | |
'input-lg' : this.props.inputSize == 'large', | |
'input-sm' : this.props.inputSize == 'small' | |
}); | |
switch(this.props.type) | |
{ | |
case 'withIcon': | |
contentHtml = this._renderWithIcon(inputType, fieldClass, inputClass); | |
break; | |
default: | |
contentHtml = this._renderDefault(inputType, fieldClass, inputClass); | |
break; | |
} | |
/* jshint ignore:start */ | |
return ( | |
React.createElement("div", null, | |
contentHtml | |
) | |
); | |
/* jshint ignore:end */ | |
} | |
}); | |
Test = React.createClass({displayName: 'Test', | |
getInitialState: function() { | |
return { | |
source: '', | |
value: '', | |
isValid: true | |
}; | |
}, | |
_handleInputChange: function(source, value, isValid) { | |
this.setState({ | |
source: source, | |
value: value, | |
isValid: isValid | |
}) | |
}, | |
render: function() { | |
/* jshint ignore:start */ | |
return ( | |
React.createElement("div", null, | |
React.createElement("p", null, | |
"Source is: ", React.createElement("code", null, this.state.source), React.createElement("br", null), | |
"value is: ", React.createElement("code", null, this.state.value), React.createElement("br", null), | |
"isInputValid: ", React.createElement("code", null, this.state.isValid.toString()) | |
), | |
React.createElement("h4", null, "Type 1 showcase - regular input field"), | |
React.createElement(InputField, {name: "Regular", label: "[Regular]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "RegularRequired", label: "[RegularRequired]", onChange: this._handleInputChange, required: true}), | |
React.createElement(InputField, {name: "NumberOnly", inputType: "number", label: "[NumberOnly]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "Password", inputType: "password", label: "[Password]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "Email", inputType: "email", label: "[Email]", onChange: this._handleInputChange}), | |
React.createElement(InputField, {name: "CustomRegex", inputType: "text", label: "[CustomRegex] numbers only ex: /^\\d+$/", validationRegex: /^\d+$/, onChange: this._handleInputChange}), | |
React.createElement("hr", null), | |
React.createElement("h4", null, "Other Variation"), | |
React.createElement(InputField, {name: "RegularLarge", label: "[RegularLarge]", onChange: this._handleInputChange, inputSize: "large"}), | |
React.createElement(InputField, {name: "RegularLarge", label: "[RegularLarge]", onChange: this._handleInputChange, inputSize: "small"}), | |
React.createElement(InputField, {name: "Range", label: "[Range]", inputType: "range", onChange: this._handleInputChange, min: 0, max: 100}), | |
React.createElement(InputField, {name: "Placeholder", placeholder: "placeholder (no label)", onChange: this._handleInputChange}), | |
React.createElement("hr", null), | |
React.createElement("h4", null, "Type 2 showcase - input with icon"), | |
React.createElement(InputField, {type: "withIcon", name: "IconInputUsingText", iconText: "$", onChange: this._handleInputChange}), | |
React.createElement(InputField, {type: "withIcon", name: "IconInputUsingClass", iconClassName: "glyphicon glyphicon-search", onChange: this._handleInputChange}) | |
) | |
); | |
/* jshint ignore:end */ | |
} | |
}); | |
var regex = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9]+$/gi; | |
var ExampleApp = React.createClass({displayName: 'ExampleApp', | |
render: function() { | |
return ( | |
/*jshint ignore:start */ | |
React.createElement("div", {className: "container"}, | |
React.createElement("h2", null, "Input Field Test Cases"), | |
React.createElement(Test, null) | |
) | |
/*jshint ignore:end */ | |
); | |
} | |
}); | |
React.render( | |
/*jshint ignore:start */ | |
React.createElement(ExampleApp, null), | |
/*jshint ignore:end */ | |
document.getElementById('app') | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment