Rift.IO OSM R1 Initial Submission
[osm/UI.git] / skyquake / framework / widgets / text-input / check-box / rw.check-box.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 check-box component.
26 * It's props values and a brief description below
27 *
28 * label: The label for the checkbox group.
29 * checkboxes: The object that creates each checkbox. Each object has a property "label" and "checked".
30 * label: The label for the individual checkbox.
31 * checked: If set to true, the individual checkbox 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: "CheckBox",
43 mixins:[ButtonEventListenerMixin],
44 propTypes: {
45 label: React.PropTypes.string,
46 checkboxes: React.PropTypes.arrayOf(
47 React.PropTypes.shape(
48 {
49 label: React.PropTypes.string,
50 checked: React.PropTypes.bool,
51 indeterminate: React.PropTypes.bool
52 }
53 )),
54 requiredText: React.PropTypes.string,
55 instructionText: React.PropTypes.string,
56 errorText: 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 },
63
64
65 /**
66 * Sets the default input state.
67 * If there is no description for the variable, assume it's the same as it's props counterpart.
68 *
69 * isActive: Boolean to indicate if input is active.
70 * isHovered: Boolean to indicate if the input is being hovered over.
71 * isFocused: Boolean to indicate if the input has been focused.
72 * isDisabled: Boolean to indicate if input has been disabled.
73 *
74 * @returns {{sizeOfButton: (*|string), isActive: boolean, isHovered: boolean, isFocused: boolean, isDisabled: (*|boolean),
75 * isReadOnly: (*|.textInput.isReadOnly|.exports.propTypes.isReadOnly|.exports.getInitialState.isReadOnly|boolean),
76 * isRequired: (*|.textInput.isRequired|.exports.propTypes.isRequired|.exports.getInitialState.isRequired|isRequired|null),
77 * isValid: null, isSuccess: null}}
78 */
79 getInitialState: function() {
80
81 return {
82 mounted: false,
83 label: this.props.label || "",
84 requiredText: this.props.requiredText || "Required",
85 instructionsText: this.props.instructions || "",
86 errorText: this.props.errorText || "",
87 size: this.props.size || '',
88 isActive: false,
89 isHovered: false,
90 isFocused: false,
91 isDisabled: this.props.disabled || false,
92 isReadOnly: this.props.isReadOnly || false,
93 isRequired: this.props.isRequired || null,
94 isValid: null, // Three way bool. Valid: true. Invalid: false. Not acted on: null.
95 isSuccess: null // Three way bool. Success: true. Error: false. Not acted on: null.
96 }
97 },
98
99 /**
100 * If any of the state variables have changed, the component should update.
101 * "nextProps" and "nextState" hold the state and property variables as they will be after the update.
102 * "this.props" and "this.state" hold the state and property variables as they were before the update.
103 * returns true if the state have changed. Otherwise returns false.
104 * @param nextProps
105 * @param nextState
106 * @returns {boolean}
107 */
108 shouldComponentUpdate: function(nextProps, nextState) {
109 var currentStateString = this.state.isReadOnly + this.state.isDisabled + this.state.isActive + this.state.isFocused +
110 this.state.isHovered + this.state.isValid + this.state.isSuccess;
111 var nextStateString = nextState.isReadOnly + nextState.isDisabled + nextState.isActive + nextState.isFocused +
112 nextState.isHovered + nextState.isValid + nextState.isSuccess;
113 if (currentStateString == nextStateString) {
114 return false;
115 }
116 return true;
117 },
118
119 componentDidMount: function() {
120 this.state.mounted = true;
121 this.render();
122 },
123
124 /**
125 * Returns a string reflecting the current state of the input.
126 * If the component state "isDisabled" is true, returns a string "disabled".
127 * If the component state "isReadOnly" is true, returns a string "readonly".
128 * Otherwise returns a string containing a word for each state that has been set to true.
129 * (ie "active focused" if the states active and focused are true, but hovered is false).
130 * @returns {string}
131 */
132 setComponentState: function() {
133
134 var ret = "";
135 if (this.state.isDisabled) {
136 return "disabled";
137 }
138 if (this.state.isReadOnly) {
139 return "readonly";
140 }
141 if (this.state.isActive) {
142 ret += "active ";
143 }
144 if (this.state.isHovered) {
145 ret += "hovered ";
146 }
147 if (this.state.isFocused) {
148 ret += "focused ";
149 }
150 return ret;
151 },
152
153 localOnClick: function(e) {
154 this.onClick(e);
155 },
156
157 /**
158 * Renders the checkbox component.
159 *
160 **/
161 render: function() {
162 var input = [];
163 var checkbox = [];
164 var label = [];
165 var input_style = {};
166 var input_state = this.setComponentState();
167
168 // The group label element
169 label = React.createElement("label", {className: "rw-form__label"}, this.props.label);
170
171 // Creates each individual checkbox element and the label for each.
172 for (var i = 0; i < this.props.checkboxes.length; i++) {
173 checkbox[i] = React.createElement("input",{
174 key: i,
175 defaultChecked: this.props.checkboxes[i].checked,
176 //indeterminate: true,
177 type: "checkbox",
178 readOnly: this.props.readonly,
179 disabled: this.props.disabled,
180 onClick: this.localOnClick,
181 onMouseUp: this.onMouseUp,
182 onMouseDown: this.onMouseDown,
183 onMouseOver: this.onMouseOver,
184 onMouseEnter: this.onMouseEnter,
185 onMouseLeave: this.onMouseLeave,
186 onMouseOut: this.onMouseOut,
187 onTouchCancel: this.onTouchCancel,
188 onTouchEnd: this.onTouchEnd,
189 onTouchMove: this.onTouchMove,
190 onTouchStart: this.onTouchStart,
191 onKeyDown: this.onKeyDown,
192 onKeyPress: this.onKeyPress,
193 onKeyUp: this.onKeyUp,
194 onFocus: this.onFocus,
195 onBlur: this.onBlur
196 }, null);
197 if (this.state.mounted) {
198 this.getDOMNode().children[i + 1].children[0].indeterminate = this.props.checkboxes[i].indeterminate;
199 }
200
201
202 input[i] = React.createElement("label", {className: "rw-form__label-checkBox", key:i, readOnly:this.props.readonly, disabled:this.props.disabled}, checkbox[i], this.props.checkboxes[i].label);
203
204 }
205
206 // The "if required" element. It displays a label if the element is required.
207 if(this.props.isRequired == true){
208 var requiredEle = React.createElement("small", {className: "rw-form__required-label"}, this.state.requiredText);
209 }
210
211 // The "error" element. It pops up as a message if there is an error with the input.
212 if(this.state.errorText != "") {
213 var error = React.createElement("p", {className: "rw-form__message-error"}, this.state.errorText);
214 }
215
216 // The "instruction" element.
217 if(this.state.instructionsText != ""){
218 var instructions = React.createElement("p", {className: "rw-form-instructions"}, this.state.instructionsText)
219 }
220
221 // The parent element for all.
222 var ret = React.createElement("div", {
223 "data-state": input_state,
224 required: this.state.isRequired,
225 disabled: this.state.isDisabled,
226 readOnly: this.state.isReadOnly,
227 className: "rw-form"
228
229 }, requiredEle, label, input, error, instructions);
230
231 return ret;
232 }
233 });