4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 var React
= require('react');
21 var ButtonEventListenerMixin
= require('../mixins/ButtonEventListener.js');
25 * A text input component.
26 * It's props values and a brief description below
28 * value: Holds the initial text content of the input.
29 * label: The text content of the label.
30 * requiredText: The text content of the "if required" message.
31 * errorText: The text content of the error message.
32 * placeholder: The initial placeholder text of the input
33 * ClassName: Css Classes applied to the element.
34 * rows: Number of text lines the input element displays at one time.
35 * cols: Number of characters per line.
36 * resizable: If the input element is resizable.
37 * isRequired: A boolean indicating whether or not the input is required.
38 * isDisabled: A boolean indicating the disabled state of the element.
39 * isReadONly: A boolean indicating whether or not the input is read only.
40 * maxLength: The hard limit on how many characters can be in the input.
42 module
.exports
= React
.createClass({
43 displayName
: "TextArea",
44 mixins
:[ButtonEventListenerMixin
],
46 value
: React
.PropTypes
.string
,
47 label
: React
.PropTypes
.string
,
48 requiredText
: React
.PropTypes
.string
,
49 errorText
: React
.PropTypes
.string
,
50 placeholder
: React
.PropTypes
.string
,
51 className
: React
.PropTypes
.string
,
52 rows
: React
.PropTypes
.number
,
53 cols
: React
.PropTypes
.number
,
54 resizable
: React
.PropTypes
.bool
,
55 isRequired
: React
.PropTypes
.bool
,
56 isDisabled
: React
.PropTypes
.bool
,
57 isReadOnly
: React
.PropTypes
.bool
,
58 maxLength
: React
.PropTypes
.number
,
59 instructions
: React
.PropTypes
.string
64 * Sets the default input state.
65 * If there is no description for the variable, assume it's the same as it's props counterpart.
67 * value: Holds the current text contents of the input element.
68 * isActive: Boolean to indicate if input is active.
69 * isHovered: Boolean to indicate if the input is being hovered over.
70 * isFocused: Boolean to indicate if the input has been focused.
71 * isDisabled: Boolean to indicate if input has been disabled.
73 * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
74 * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
75 * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
76 * isValid: null, isSuccess: null}}
78 getInitialState: function() {
80 value
: this.props
.value
|| "",
81 label
: this.props
.label
|| "",
82 requiredText
: this.props
.requiredText
|| "Required",
83 errorText
: this.props
.errorText
|| "",
84 instructionsText
: this.props
.instructions
|| "",
88 isDisabled
: this.props
.isDisabled
|| false,
89 isReadOnly
: this.props
.isReadOnly
|| false,
90 isRequired
: this.props
.isRequired
|| null,
91 isValid
: null, // Three way bool. Valid: true. Invalid: false. Not acted on: null.
92 isSuccess
: null // Three way bool. Success: true. Error: false. Not acted on: null.
98 * If any of the state variables have changed, the component should update.
99 * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
100 * "this.props" and "this.state" hold the state and property variables as they were before the update.
101 * returns true if the state have changed. Otherwise returns false.
106 shouldComponentUpdate: function(nextProps
, nextState
) {
107 var currentStateString
= this.state
.isReadOnly
+ this.state
.isDisabled
+ this.state
.isActive
+ this.state
.isFocused
+
108 this.state
.isHovered
+ this.state
.isValid
+ this.state
.isSuccess
+ this.state
.value
;
109 var nextStateString
= nextState
.isReadOnly
+ nextState
.isDisabled
+ nextState
.isActive
+ nextState
.isFocused
+
110 nextState
.isHovered
+ nextState
.isValid
+ nextState
.isSuccess
+ nextState
.value
;
111 if (currentStateString
== nextStateString
) {
117 * Makes sure that when the user types new input, the contents of the input changes accordingly.
121 handleChange: function(event
) {
122 this.setState({value
:event
.target
.value
});
126 * Returns a string reflecting the current state of the input.
127 * If the component state "isDisabled" is true, returns a string "disabled".
128 * If the component state "isReadOnly" is true, returns a string "readonly".
129 * Otherwise returns a string containing a word for each state that has been set to true.
130 * (ie "active focused" if the states active and focused are true, but hovered is false).
133 setComponentState: function() {
135 if (this.state
.isDisabled
) {
138 if (this.state
.isReadOnly
) {
141 if (this.state
.isActive
) {
144 if (this.state
.isHovered
) {
147 if (this.state
.isFocused
) {
154 * Renders the Text Input component.
158 var value
= this.state
.value
;
160 var textarea_style
= {};
161 var textarea_state
= this.setComponentState();
163 // creates a style for the "resizable" attribute.
164 if (!this.props
.resizable
) {
165 textarea_style
.resize
= "none";
168 // The input element.
169 input
= React
.createElement("textarea", {
171 "data-state": textarea_state
,
173 "style": textarea_style
,
174 placeholder
: this.props
.placeholder
,
175 rows
: this.props
.rows
,
176 cols
: this.props
.cols
,
177 maxLength
: this.props
.maxLength
,
178 required
: this.state
.isRequired
,
179 disabled
: this.state
.isDisabled
,
180 readOnly
: this.state
.isReadOnly
,
181 onChange
: this.handleChange
,
182 onClick
: this.onClick
,
183 onMouseUp
: this.onMouseUp
,
184 onMouseDown
: this.onMouseDown
,
185 onMouseOver
: this.onMouseOver
,
186 onMouseEnter
: this.onMouseEnter
,
187 onMouseLeave
: this.onMouseLeave
,
188 onMouseOut
: this.onMouseOut
,
189 onTouchCancel
: this.onTouchCancel
,
190 onTouchEnd
: this.onTouchEnd
,
191 onTouchMove
: this.onTouchMove
,
192 onTouchStart
: this.onTouchStart
,
193 onKeyDown
: this.onKeyDown
,
194 onKeyPress
: this.onKeyPress
,
195 onKeyUp
: this.onKeyUp
,
196 onFocus
: this.onFocus
,
198 className
: (this.props
.className
|| "rw-textarea"),
204 // The "if required" element. It displays a label if the element is required.
205 if(this.props
.isRequired
== true){
206 var requiredEle
= React
.createElement("small", {className
: "rw-form-requiredLabel"}, this.state
.requiredText
);
209 // The label element associated with the input.
210 var label
= React
.createElement("label", null, this.state
.label
, requiredEle
, input
);
212 // The "error" element. It pops up as a message if there is an error with the input.
213 if(this.state
.errorText
!= "") {
214 var error
= React
.createElement("p", {className
: "rw-form-errorMsg"}, this.state
.errorText
);
218 if(this.state
.instructionsText
!= ""){
219 var instructions
= React
.createElement("p", {className
: "rw-form-instructions"}, this.state
.instructionsText
)
222 // The parent element for all.
223 var ret
= React
.createElement("div", {
224 "data-state": textarea_state
,
225 required
: this.state
.isRequired
,
226 disabled
: this.state
.isDisabled
,
227 readOnly
: this.state
.isReadOnly
228 }, label
, error
, instructions
);