Supports select, textarea, static as well as standard HTML input types. getValue() returns an array for multiple select.
+
Button Input Types
+
Form buttons are encapsulated by ButtonInput. Pass in type="reset" or type="submit" to suit your needs. Styling is the same as Button.
+
Add-ons
Use addonBefore and addonAfter for normal addons, buttonBefore and buttonAfter for button addons.
Exotic configurations may require some css on your side.
diff --git a/docs/src/ReactPlayground.js b/docs/src/ReactPlayground.js
index 1d9152678b..7d2491aa9c 100644
--- a/docs/src/ReactPlayground.js
+++ b/docs/src/ReactPlayground.js
@@ -5,6 +5,7 @@ import * as modAlert from '../../src/Alert';
import * as modBadge from '../../src/Badge';
import * as modmodButton from '../../src/Button';
import * as modButtonGroup from '../../src/ButtonGroup';
+import * as modButtonInput from '../../src/ButtonInput';
import * as modmodButtonToolbar from '../../src/ButtonToolbar';
import * as modCollapsibleNav from '../../src/CollapsibleNav';
import * as modCollapsibleMixin from '../../src/CollapsibleMixin';
@@ -52,6 +53,7 @@ const Alert = modAlert.default;
const Badge = modBadge.default;
const Button = modmodButton.default;
const ButtonGroup = modButtonGroup.default;
+const ButtonInput = modButtonInput.default;
const ButtonToolbar = modmodButtonToolbar.default;
const CollapsibleNav = modCollapsibleNav.default;
const CollapsibleMixin = modCollapsibleMixin.default;
diff --git a/docs/src/Samples.js b/docs/src/Samples.js
index d4821d9d10..82d9c40928 100644
--- a/docs/src/Samples.js
+++ b/docs/src/Samples.js
@@ -83,6 +83,7 @@ export default {
TableResponsive: require('fs').readFileSync(__dirname + '/../examples/TableResponsive.js', 'utf8'),
Input: require('fs').readFileSync(__dirname + '/../examples/Input.js', 'utf8'),
InputTypes: require('fs').readFileSync(__dirname + '/../examples/InputTypes.js', 'utf8'),
+ ButtonInput: require('fs').readFileSync(__dirname + '/../examples/ButtonInput.js', 'utf8'),
InputAddons: require('fs').readFileSync(__dirname + '/../examples/InputAddons.js', 'utf8'),
InputSizes: require('fs').readFileSync(__dirname + '/../examples/InputSizes.js', 'utf8'),
InputValidation: require('fs').readFileSync(__dirname + '/../examples/InputValidation.js', 'utf8'),
diff --git a/src/ButtonInput.js b/src/ButtonInput.js
new file mode 100644
index 0000000000..846d577ed4
--- /dev/null
+++ b/src/ButtonInput.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import Button from './Button';
+import FormGroup from './FormGroup';
+import InputBase from './InputBase';
+
+function valueValidation({children, value}, propName, componentName) {
+ if (children && value) {
+ return new Error('Both value and children cannot be passed to ButtonInput');
+ }
+ return React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number]).call(null, {children, value}, propName, componentName);
+}
+
+class ButtonInput extends InputBase {
+ renderFormGroup(children) {
+ let {bsStyle, value, ...other} = this.props; /* eslint no-unused-vars: 0 object-shorthand: 0 */
+ return {children};
+ }
+
+ renderInput() {
+ let {children, value, ...other} = this.props;
+ let val = children ? children : value;
+ return ;
+ }
+}
+
+ButtonInput.defaultProps = {
+ type: 'button'
+};
+
+ButtonInput.propTypes = {
+ type: React.PropTypes.oneOf(['button', 'reset', 'submit']),
+ bsStyle(props) {
+ //defer to Button propTypes of bsStyle
+ return null;
+ },
+ children: valueValidation,
+ value: valueValidation
+};
+
+export default ButtonInput;
diff --git a/src/Input.js b/src/Input.js
index d0870481cc..61456c70c3 100644
--- a/src/Input.js
+++ b/src/Input.js
@@ -1,239 +1,19 @@
import React from 'react';
-import classNames from 'classnames';
-import Button from './Button';
-import FormGroup from './FormGroup';
+import InputBase from './InputBase';
+import ButtonInput from './ButtonInput';
+import deprecationWarning from './utils/deprecationWarning';
-class Input 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 ? (
-
- {this.props.addonBefore}
-
- ) : null;
-
- let addonAfter = this.props.addonAfter ? (
-
- {this.props.addonAfter}
-
- ) : null;
-
- let buttonBefore = this.props.buttonBefore ? (
-
- {this.props.buttonBefore}
-
- ) : null;
-
- let buttonAfter = this.props.buttonAfter ? (
-
- {this.props.buttonAfter}
-
- ) : 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 ? (
-