@samitouri / QOS-React-2 / commits / 0c6f4b3bcc
Fork 0

The library for web and native user interfaces.

Set textarea value when changing content

At http://jsfiddle.net/spicyj/W4QLq/, typing into the textbox would cause clicking the button to do nothing; now it should work.

Ben Alpert committed Jun 12, 2013 at 00:14 UTC 0c6f4b3bcc8dc728f4736e53e3d81d6ae4c47cb9
4 files changed +133 -1
src/core/ReactDOM.js
+1
@@ -115,6 +115,7 @@ var ReactDOM = objMapKeyVal({
115 table: false,
116 tbody: false,
117 td: false,
118 + // Danger: this gets monkeypatched! See ReactDOMTextarea for more info.
119 textarea: false,
120 tfoot: false,
121 th: false,
src/core/ReactDOMTextarea.js new
+63
@@ -0,0 +1,63 @@
1 +/**
2 + * Copyright 2013 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @providesModule ReactDOMTextarea
17 + */
18 +
19 +"use strict";
20 +
21 +var ReactCompositeComponent = require('ReactCompositeComponent');
22 +var ReactDOM = require('ReactDOM');
23 +
24 +var invariant = require('invariant');
25 +
26 +// Store a reference to the <textarea> `ReactNativeComponent`.
27 +var textarea = ReactDOM.textarea;
28 +
29 +// For quickly matching children type, to test if can be treated as content.
30 +var CONTENT_TYPES = {'string': true, 'number': true};
31 +
32 +var getTextContent = function(props) {
33 + return props.content != null ? '' + props.content :
34 + CONTENT_TYPES[typeof props.children] ? '' + props.children : '';
35 +};
36 +
37 +/**
38 + * Since setting .textContent on a dirty <textarea> doesn't update its value,
39 + * we intercept prop changes here to make sure that value is updated.
40 + */
41 +var ReactDOMTextarea = ReactCompositeComponent.createClass({
42 + render: function() {
43 + invariant(
44 + this.props.dangerouslySetInnerHTML == null,
45 + '`dangerouslySetInnerHTML` does not make sense on textarea.'
46 + );
47 + invariant(
48 + this.props.children == null || CONTENT_TYPES[typeof this.props.children],
49 + 'When present, textarea children must be a single string or number.'
50 + );
51 + return this.transferPropsTo(textarea(null, this.props.children));
52 + },
53 +
54 + componentDidUpdate: function(prevProps, prevState, rootNode) {
55 + var oldContent = getTextContent(prevProps);
56 + var newContent = getTextContent(this.props);
57 + if (oldContent !== newContent) {
58 + rootNode.value = newContent;
59 + }
60 + }
61 +});
62 +
63 +module.exports = ReactDOMTextarea;
src/core/ReactDefaultInjection.js
+3 -1
@@ -20,6 +20,7 @@
20
21 var ReactDOM = require('ReactDOM');
22 var ReactDOMForm = require('ReactDOMForm');
23 +var ReactDOMTextarea = require('ReactDOMTextarea');
24
25 var DefaultEventPluginOrder = require('DefaultEventPluginOrder');
26 var EnterLeaveEventPlugin = require('EnterLeaveEventPlugin');
@@ -50,7 +51,8 @@ function inject() {
51 * dependency graph we need to inject it here.
52 */
53 ReactDOM.injection.injectComponentClasses({
53 - form: ReactDOMForm
54 + form: ReactDOMForm,
55 + textarea: ReactDOMTextarea
56 });
57 }
58
src/core/__tests__/ReactDOMTextarea-test.js new
+66
@@ -0,0 +1,66 @@
1 +/**
2 + * Copyright 2013 Facebook, Inc.
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + *
16 + * @jsx React.DOM
17 + * @emails react-core
18 + */
19 +
20 +"use strict";
21 +
22 +describe('ReactDOMTextarea', function() {
23 + var React;
24 + var ReactTestUtils;
25 + var transaction;
26 +
27 + beforeEach(function() {
28 + React = require('React');
29 + ReactTestUtils = require('ReactTestUtils');
30 +
31 + var ReactReconcileTransaction = require('ReactReconcileTransaction');
32 + transaction = new ReactReconcileTransaction();
33 + });
34 +
35 + it("should remove value with removed children", function() {
36 + var stub = ReactTestUtils.renderIntoDocument(<textarea>giraffe</textarea>);
37 +
38 + expect(stub.getDOMNode().value).toEqual('giraffe');
39 + stub.receiveProps({ children: null }, transaction);
40 + expect(stub.getDOMNode().value).toEqual('');
41 + });
42 +
43 + it("should update value with a single string child", function() {
44 + var stub = ReactTestUtils.renderIntoDocument(<textarea>monkey</textarea>);
45 +
46 + expect(stub.getDOMNode().value).toEqual('monkey');
47 + stub.receiveProps({ children: 'gorilla' }, transaction);
48 + expect(stub.getDOMNode().value).toEqual('gorilla');
49 + });
50 +
51 + it("should update value with a single numerical child", function() {
52 + var stub = ReactTestUtils.renderIntoDocument(<textarea>17</textarea>);
53 +
54 + expect(stub.getDOMNode().value).toEqual('17');
55 + stub.receiveProps({ children: 289 }, transaction);
56 + expect(stub.getDOMNode().value).toEqual('289');
57 + });
58 +
59 + it("should update value with the content property", function() {
60 + var stub = ReactTestUtils.renderIntoDocument(<textarea content="purple" />);
61 +
62 + expect(stub.getDOMNode().value).toEqual('purple');
63 + stub.receiveProps({ content: 'eggplant' }, transaction);
64 + expect(stub.getDOMNode().value).toEqual('eggplant');
65 + });
66 +});