Skip to content

Instantly share code, notes, and snippets.

@Troush
Created November 3, 2014 11:15
Show Gist options
  • Save Troush/611832d2623162cb862c to your computer and use it in GitHub Desktop.
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/
/** @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