Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / framework / widgets / radio-button / rw.radio-button.js
1
2 /*
3 *
4 * Copyright 2016 RIFT.IO Inc
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 */
19
20 var React = require('react');
21 var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js');
22
23
24 /**
25 * A radio-button component.
26 * It's props values and a brief description below
27 *
28 * label: The label for the radio button group.
29 * radiobuttons: The object that creates each radio button. Each object has a property "label" and "checked".
30 * label: The label for the individual radio button.
31 * checked: If set to true, the individual radio button is initialized with a check.
32 * requiredText: The text content of the "if required" message.
33 * errorText: The text content of the error message.
34 * ClassName: Css Classes applied to the element.
35 * size: The size of the element.
36 * isRequired: A boolean indicating whether or not the input is required.
37 * isDisabled: A boolean indicating the disabled state of the element.
38 * isReadOnly: A boolean indicating whether or not the input is read only.
39 * instructions: The text content of the instructions
40 **/
41 module.exports = React.createClass({
42 displayName: "RadioButton",
43 mixins:[ButtonEventListenerMixin],
44 propTypes: {
45 name: React.PropTypes.string,
46 label: React.PropTypes.string,
47 radiobuttons: React.PropTypes.arrayOf(
48 React.PropTypes.shape(
49 {
50 label: React.PropTypes.string,
51 checked: React.PropTypes.bool
52 }
53 )),
54 requiredText: React.PropTypes.string,
55 errorText: React.PropTypes.string,
56 placeholder: React.PropTypes.string,
57 className: React.PropTypes.string,
58 size: React.PropTypes.string,
59 isRequired: React.PropTypes.bool,
60 isDisabled: React.PropTypes.bool,
61 isReadOnly: React.PropTypes.bool,
62 instructions: React.PropTypes.string
63 },
64
65
66 /**
67 * Sets the default input state.
68 * If there is no description for the variable, assume it's the same as it's props counterpart.
69 *
70 * isActive: Boolean to indicate if input is active.
71 * isHovered: Boolean to indicate if the input is being hovered over.
72 * isFocused: Boolean to indicate if the input has been focused.
73 * isDisabled: Boolean to indicate if input has been disabled.
74 *
75 * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
76 * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
77 * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
78 * isValid: null, isSuccess: null}}
79 */
80 getInitialState: function() {
81 return {
82 label: this.props.label || "",
83 requiredText: this.props.requiredText || "Required",
84 instructionsText: this.props.instructions || "",
85 errorText: this.props.errorText || "",
86 size: this.props.size || '',
87 isActive: false,
88 isHovered: false,
89 isFocused: false,
90 isDisabled: this.props.disabled || false,
91 isReadOnly: this.props.isReadOnly || false,
92 isRequired: this.props.isRequired || null,
93 isValid: null, // Three way bool. Valid: true. Invalid: false. Not acted on: null.
94 isSuccess: null // Three way bool. Success: true. Error: false. Not acted on: null.
95 }
96 },
97
98 /**
99 * If any of the state variables have changed, the component should update.
100 * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
101 * "this.props" and "this.state" hold the state and property variables as they were before the update.
102 * returns true if the state have changed. Otherwise returns false.
103 * @param nextProps
104 * @param nextState
105 * @returns {boolean}
106 */
107 shouldComponentUpdate: function(nextProps, nextState) {
108 var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
109 this.state.isHovered + this.state.isValid + this.state.isSuccess;
110 var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
111 nextState.isHovered + nextState.isValid + nextState.isSuccess;
112 if (currentStateString == nextStateString) {
113 return false;
114 }
115 return true;
116 },
117
118
119
120 /**
121 * Returns a string reflecting the current state of the input.
122 * If the component state "isDisabled" is true, returns a string "disabled".
123 * If the component state "isReadOnly" is true, returns a string "readonly".
124 * Otherwise returns a string containing a word for each state that has been set to true.
125 * (ie "active focused" if the states active and focused are true, but hovered is false).
126 * @returns {string}
127 */
128 setComponentState: function() {
129 var ret = "";
130 if (this.state.isDisabled) {
131 return "disabled";
132 }
133 if (this.state.isReadOnly) {
134 return "readonly";
135 }
136 if (this.state.isActive) {
137 ret += "active ";
138 }
139 if (this.state.isHovered) {
140 ret += "hovered ";
141 }
142 if (this.state.isFocused) {
143 ret += "focused ";
144 }
145 return ret;
146 },
147
148 /**
149 * Renders the Text Input component.
150 *
151 **/
152 render: function() {
153 var input = [];
154 var label = [];
155 var input_style = {};
156 var input_state = this.setComponentState();
157
158 // The following if statements translates the min/max width from a number into a string.
159 if (this.props.minWidth) {
160 input_style['min-width'] = String(this.props.minWidth) + 'px';
161 }
162 if (this.props.maxWidth) {
163 input_style['max-width'] = String(this.props.maxWidth) + 'px';
164 }
165
166 //// The input element.
167 //input = React.createElement("input", {
168 // ref: "inputRef",
169 // "data-state": input_state,
170 // "type": "checkbox",
171 // placeholder: this.props.placeholder,
172 // pattern: this.props.pattern,
173 // maxLength: this.props.maxLength,
174 // required: this.state.isRequired,
175 // disabled: this.state.isDisabled,
176 // readOnly: this.state.isReadOnly,
177 // onChange: this.handleChange,
178 // onClick: this.onClick,
179 // onMouseUp: this.onMouseUp,
180 // onMouseDown: this.onMouseDown,
181 // onMouseOver: this.onMouseOver,
182 // onMouseEnter: this.onMouseEnter,
183 // onMouseLeave: this.onMouseLeave,
184 // onMouseOut: this.onMouseOut,
185 // onTouchCancel: this.onTouchCancel,
186 // onTouchEnd: this.onTouchEnd,
187 // onTouchMove: this.onTouchMove,
188 // onTouchStart: this.onTouchStart,
189 // onKeyDown: this.onKeyDown,
190 // onKeyPress: this.onKeyPress,
191 // onKeyUp: this.onKeyUp,
192 // onFocus: this.onFocus,
193 // onBlur: this.onBlur,
194 // className: (this.props.className || "rw-textinput"),
195 // tabIndex: 0
196 // },
197 // null
198 //);
199
200 label = React.createElement("label", null, this.props.label);
201
202 for (var i = 0; i < this.props.radiobuttons.length; i++) {
203
204 // Label for the whole radio button group
205 input[i] = React.createElement("label",
206 {
207 key:i*2 + 1,
208 readOnly:this.props.readonly,
209 disabled:this.props.disabled
210 },
211
212 // Creates each radio button input element.
213 React.createElement("input", {
214 key: i*2,
215 defaultChecked: this.props.radiobuttons[i].checked,
216 type: "radio",
217 name: this.props.name,
218 readOnly: this.props.readonly,
219 disabled: this.props.disabled,
220 onClick: this.onClick,
221 onMouseUp: this.onMouseUp,
222 onMouseDown: this.onMouseDown,
223 onMouseOver: this.onMouseOver,
224 onMouseEnter: this.onMouseEnter,
225 onMouseLeave: this.onMouseLeave,
226 onMouseOut: this.onMouseOut,
227 onTouchCancel: this.onTouchCancel,
228 onTouchEnd: this.onTouchEnd,
229 onTouchMove: this.onTouchMove,
230 onTouchStart: this.onTouchStart,
231 onKeyDown: this.onKeyDown,
232 onKeyPress: this.onKeyPress,
233 onKeyUp: this.onKeyUp,
234 onFocus: this.onFocus,
235 onBlur: this.onBlur
236 },
237 null
238 ),
239 this.props.radiobuttons[i].label);
240 }
241
242 // The "if required" element. It displays a label if the element is required.
243 if(this.props.isRequired == true){
244 var requiredEle = React.createElement("small", {className: "rw-form-requiredLabel"}, this.state.requiredText);
245 }
246
247 // The "error" element. It pops up as a message if there is an error with the input.
248 if(this.state.errorText != "") {
249 var error = React.createElement("p", {className: "rw-form-errorMsg"}, this.state.errorText);
250 }
251
252 // The "instruction" element.
253 if(this.state.instructionsText != ""){
254 var instructions = React.createElement("p", {className: "rw-form-instructions"}, this.state.instructionsText)
255 }
256
257 // The parent element for all.
258 var ret = React.createElement("div", {
259 "data-state": input_state,
260 required: this.state.isRequired,
261 disabled: this.state.isDisabled,
262 readOnly: this.state.isReadOnly
263 }, requiredEle, label, input, error, instructions);
264
265 return ret;
266 }
267 });