diff --git a/src/browser/ui/dom/components/ReactDOMInput.js b/src/browser/ui/dom/components/ReactDOMInput.js index 1fd4351251617..b86cf779530ef 100644 --- a/src/browser/ui/dom/components/ReactDOMInput.js +++ b/src/browser/ui/dom/components/ReactDOMInput.js @@ -84,7 +84,21 @@ var ReactDOMInput = ReactCompositeComponent.createClass({ var checked = LinkedValueUtils.getChecked(this); props.checked = checked != null ? checked : this.state.initialChecked; - props.onChange = this._handleChange; + // Skip attaching top-level event handlers to an uncontrolled input with no + // onChange handler -- in the case of radio buttons, we still need the + // handler even if this radio button is "uncontrolled" because clicking A in + // + // + // shouldn't uncheck B. (If we had a "weak listen" operation that put the + // listener but didn't attach the handlers to the DOM, we could use that + // instead for uncontrolled radios.) + if (value != null || checked != null || + LinkedValueUtils.getOnChange(this) != null || + this.props.type === "radio") { + props.onChange = this._handleChange; + } else { + props.onChange = null; + } return input(props, this.props.children); }, diff --git a/src/browser/ui/dom/components/ReactDOMSelect.js b/src/browser/ui/dom/components/ReactDOMSelect.js index 3b965c60bad48..2dd29b9d87550 100644 --- a/src/browser/ui/dom/components/ReactDOMSelect.js +++ b/src/browser/ui/dom/components/ReactDOMSelect.js @@ -30,11 +30,10 @@ var merge = require('merge'); // Store a reference to the element (array of option values + * if this.props.multiple, otherwise a single option value). + */ +function getSelectedValue(component) { + var node = component.getDOMNode(); + var selectedValue; + if (component.props.multiple) { + selectedValue = []; + var options = node.options; + for (var i = 0, l = options.length; i < l; i++) { + if (options[i].selected) { + selectedValue.push(options[i].value); + } + } + } else { + selectedValue = node.value; + } + return selectedValue; +} + /** * Implements a