UNPKG

react-bootstrap

Version:

Bootstrap 3 components build with React

227 lines (196 loc) 6.04 kB
import React from 'react'; import classNames from 'classnames'; import FormGroup from './FormGroup'; class InputBase extends React.Component { getInputDOMNode() { return React.findDOMNode(this.refs.input); } getValue() { if (this.props.type === 'static') { return this.props.value; } else if (this.props.type) { if (this.props.type === 'select' && this.props.multiple) { return this.getSelectedOptions(); } else { return this.getInputDOMNode().value; } } else { throw 'Cannot use getValue without specifying input type.'; } } getChecked() { return this.getInputDOMNode().checked; } getSelectedOptions() { let values = []; Array.prototype.forEach.call( this.getInputDOMNode().getElementsByTagName('option'), (option) => { if (option.selected) { let value = option.getAttribute('value') || option.innerHtml; values.push(value); } }); return values; } isCheckboxOrRadio() { return this.props.type === 'checkbox' || this.props.type === 'radio'; } isFile() { return this.props.type === 'file'; } renderInputGroup(children) { let addonBefore = this.props.addonBefore ? ( <span className="input-group-addon" key="addonBefore"> {this.props.addonBefore} </span> ) : null; let addonAfter = this.props.addonAfter ? ( <span className="input-group-addon" key="addonAfter"> {this.props.addonAfter} </span> ) : null; let buttonBefore = this.props.buttonBefore ? ( <span className="input-group-btn"> {this.props.buttonBefore} </span> ) : null; let buttonAfter = this.props.buttonAfter ? ( <span className="input-group-btn"> {this.props.buttonAfter} </span> ) : null; let inputGroupClassName; switch (this.props.bsSize) { case 'small': inputGroupClassName = 'input-group-sm'; break; case 'large': inputGroupClassName = 'input-group-lg'; break; } return addonBefore || addonAfter || buttonBefore || buttonAfter ? ( <div className={classNames(inputGroupClassName, 'input-group')} key="input-group"> {addonBefore} {buttonBefore} {children} {addonAfter} {buttonAfter} </div> ) : children; } renderIcon() { let classes = { 'glyphicon': true, 'form-control-feedback': true, 'glyphicon-ok': this.props.bsStyle === 'success', 'glyphicon-warning-sign': this.props.bsStyle === 'warning', 'glyphicon-remove': this.props.bsStyle === 'error' }; return this.props.hasFeedback ? ( <span className={classNames(classes)} key="icon" /> ) : null; } renderHelp() { return this.props.help ? ( <span className="help-block" key="help"> {this.props.help} </span> ) : null; } renderCheckboxAndRadioWrapper(children) { let classes = { 'checkbox': this.props.type === 'checkbox', 'radio': this.props.type === 'radio' }; return ( <div className={classNames(classes)} key="checkboxRadioWrapper"> {children} </div> ); } renderWrapper(children) { return this.props.wrapperClassName ? ( <div className={this.props.wrapperClassName} key="wrapper"> {children} </div> ) : children; } renderLabel(children) { let classes = { 'control-label': !this.isCheckboxOrRadio() }; classes[this.props.labelClassName] = this.props.labelClassName; return this.props.label ? ( <label htmlFor={this.props.id} className={classNames(classes)} key="label"> {children} {this.props.label} </label> ) : children; } renderInput() { if (!this.props.type) { return this.props.children; } switch (this.props.type) { case 'select': return ( <select {...this.props} className={classNames(this.props.className, 'form-control')} ref="input" key="input"> {this.props.children} </select> ); case 'textarea': return <textarea {...this.props} className={classNames(this.props.className, 'form-control')} ref="input" key="input" />; case 'static': return ( <p {...this.props} className={classNames(this.props.className, 'form-control-static')} ref="input" key="input"> {this.props.value} </p> ); } let className = this.isCheckboxOrRadio() || this.isFile() ? '' : 'form-control'; return <input {...this.props} className={classNames(this.props.className, className)} ref="input" key="input" />; } renderFormGroup(children) { return <FormGroup {...this.props}>{children}</FormGroup>; } renderChildren() { return !this.isCheckboxOrRadio() ? [ this.renderLabel(), this.renderWrapper([ this.renderInputGroup( this.renderInput() ), this.renderIcon(), this.renderHelp() ]) ] : this.renderWrapper([ this.renderCheckboxAndRadioWrapper( this.renderLabel( this.renderInput() ) ), this.renderHelp() ]); } render() { let children = this.renderChildren(); return this.renderFormGroup(children); } } InputBase.propTypes = { type: React.PropTypes.string, label: React.PropTypes.node, help: React.PropTypes.node, addonBefore: React.PropTypes.node, addonAfter: React.PropTypes.node, buttonBefore: React.PropTypes.node, buttonAfter: React.PropTypes.node, bsSize: React.PropTypes.oneOf(['small', 'medium', 'large']), bsStyle: React.PropTypes.oneOf(['success', 'warning', 'error']), hasFeedback: React.PropTypes.bool, id: React.PropTypes.string, groupClassName: React.PropTypes.string, wrapperClassName: React.PropTypes.string, labelClassName: React.PropTypes.string, multiple: React.PropTypes.bool, disabled: React.PropTypes.bool, value: React.PropTypes.any }; export default InputBase;