Created
November 3, 2014 11:15
-
-
Save Troush/611832d2623162cb862c to your computer and use it in GitHub Desktop.
Reworked example of abstract bs components for react http://clozeit.wordpress.com/2014/01/13/bootstrap-forms-using-react-js/
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
/** @jsx React.DOM */ | |
var INPUT_TYPES = ["email", "text", "password"] | |
var Large = {getDefaultProps: function() { return {bsSize: 'lg'};}}; | |
var Medium = {getDefaultProps: function() { return {bsSize: 'md'};}}; | |
var Small = {getDefaultProps: function() { return {bsSize: 'sm'};}}; | |
var Default = {getDefaultProps: function() { return {bsStyle: 'default'};}}; | |
var Primary = {getDefaultProps: function() { return {bsStyle: 'primary'};}}; | |
var Success = {getDefaultProps: function() { return {bsStyle: 'success'};}}; | |
var Info = {getDefaultProps: function() { return {bsStyle: 'info'};}}; | |
var Warning = {getDefaultProps: function() { return {bsStyle: 'warning'};}}; | |
var Danger = {getDefaultProps: function() { return {bsStyle: 'danger'};}}; | |
var Link = {getDefaultProps: function() { return {bsStyle: 'link'};}}; | |
var BootStrapMixin = { | |
extendClassName: function() { | |
var bsClass = this.props.bsClass; | |
var bsStyle = this.props.bsStyle; | |
var bsSize = this.props.bsSize; | |
var prefix = this.props.bsClass + '-'; | |
var classes = {} | |
// TODO: Check there are no conflicting values in this.props.className | |
if(this.props.bsClass) | |
classes[this.props.bsClass] = true; | |
if(this.props.bsSize) | |
classes[prefix + this.props.bsSize] = true; | |
if(this.props.bsStyle) | |
classes[prefix + this.props.bsStyle] = true; | |
// Merge with previous classes | |
if(this.props.className) | |
this.props.className.split(' ').map( | |
function(klass){ | |
classes[klass] = true; | |
} | |
); | |
// This produces a ' ' delineated string | |
// from all members of classes that evaluate as truthy | |
return React.addons.classSet(classes); | |
}, | |
}; | |
var Input = React.createClass({ | |
propTypes: { | |
name: React.PropTypes.string.isRequired, | |
type: React.PropTypes.oneOf(INPUT_TYPES).isRequired, | |
placeholder: React.PropTypes.string, | |
label: React.PropTypes.string, | |
required: React.PropTypes.bool, | |
oneOf: React.PropTypes.array, | |
minLength: React.PropTypes.number, | |
onValChange: React.PropTypes.func | |
}, | |
getInitialState: function() { return {val:''}; }, | |
getValue: function() { | |
return this.refs.input.getDOMNode().value; | |
}, | |
renderInput: function(){ | |
var className = "form-control input-md"; | |
return <input name={this.props.name} type={this.props.type} className={className} | |
placeholder={this.props.placeholder} ref="input" onChange={this.props.onValChange}/>; | |
}, | |
renderLabel: function(){ | |
return <label>{this.props.label}</label> ? this.props.label : undefined; | |
}, | |
componentDidMount: function() { | |
}, | |
render: function(){ | |
var className = "form-group"; | |
if (this.state.error) | |
className += ' has-error'; | |
return ( | |
<div className={className} onBlur={this.onBlur} onFocus={this.onFocus}> | |
{this.renderInput()} | |
{this.renderLabel()} | |
</div> | |
); | |
}, | |
onBlur: function(e){ | |
var value = this.getValue(); | |
var error; | |
if (this.props.required && !value) | |
error = 'required'; | |
else if (this.props.oneOf && !(value in this.props.oneOf)) | |
error = 'oneOf'; | |
else if (this.props.minLength && value.length < this.props.minLength) | |
error = 'minLength'; | |
this.setState({error: error}); | |
}, | |
onFocus: function(e) { | |
this.setState({error: false}); | |
e.stopPropagation(); | |
} | |
}); | |
var Form = React.createClass({ | |
mixins: [BootStrapMixin], | |
propTypes: { | |
callback: React.PropTypes.func.isRequired, | |
values: React.PropTypes.object | |
}, | |
getDefaultProps: function() { | |
return { | |
bsClass: "form" | |
}; | |
}, | |
onSubmit: function(e) { | |
e.preventDefault(); | |
}, | |
render: function(){ | |
var className = this.extendClassName(); | |
return this.transferPropsTo( | |
<form onClick={this.onSubmit} className={className} role="form" action="#"> | |
{this.props.children} | |
</form> | |
); | |
}, | |
}); | |
var Button = React.createClass({ | |
mixins : [BootStrapMixin], | |
getDefaultProps: function() {return {bsClass: 'btn'};}, | |
render: function() { | |
return this.transferPropsTo( | |
<button className={this.extendClassName()}> | |
{this.props.children} | |
</button> | |
); | |
} | |
}); | |
var SignupButton = React.createClass({ | |
mixins : [Large, Success], | |
render: function() {return <Button>Sign Up Now!</Button>;} | |
}); | |
var LoginForm = React.createClass({ | |
getInitialState: function(){ | |
return {} | |
}, | |
componentDidMount: function() { | |
}, | |
change: function(e) { | |
var node = e.target; | |
obj = {}; | |
obj[node.name] = node.value; | |
this.setState(obj); | |
}, | |
handleLogin : function(e){ | |
console.log("Event fired:"); | |
console.log(e); | |
debugger;; | |
}, | |
render: function() { | |
return <Form bsStyle="inline" callback={this.handleLogin}> | |
<Input name="email" type="email" placeholder="Email" required={true} onValChange={this.change}/> | |
<Input name="password" type="password" placeholder="Password / Blank" | |
required={true} minLength={5} onValChange={this.change}/> | |
<Button onClick={this.handleLogin} type="#" bsStyle="success"> | |
Log in / Recover Pass | |
</Button> | |
</Form> | |
} | |
}) | |
React.renderComponent(<LoginForm />, document.getElementById("ad")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment