react 16 upgrade
[sdc.git] / openecomp-ui / src / nfvo-components / input / validation / Input.jsx
1 /*
2  * Copyright © 2016-2018 European Support Limited
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 import React from 'react';
17 import ReactDOM from 'react-dom';
18 import classNames from 'classnames';
19 import Checkbox from 'react-bootstrap/lib/Checkbox.js';
20 import Radio from 'sdc-ui/lib/react/Radio.js';
21 import FormGroup from 'react-bootstrap/lib/FormGroup.js';
22 import FormControl from 'react-bootstrap/lib/FormControl.js';
23 import Overlay from 'react-bootstrap/lib/Overlay.js';
24 import Tooltip from 'react-bootstrap/lib/Tooltip.js';
25 import Datepicker from 'nfvo-components/datepicker/Datepicker.jsx';
26
27 class Input extends React.Component {
28     state = {
29         value: this.props.value,
30         checked: this.props.checked,
31         selectedValues: []
32     };
33
34     render() {
35         /* eslint-disable no-unused-vars */
36         const {
37             label,
38             isReadOnlyMode,
39             value,
40             onBlur,
41             onKeyDown,
42             type,
43             disabled,
44             checked,
45             name
46         } = this.props;
47         const {
48             groupClassName,
49             isValid = true,
50             errorText,
51             isRequired,
52             overlayPos,
53             ...inputProps
54         } = this.props;
55         const {
56             dateFormat,
57             startDate,
58             endDate,
59             selectsStart,
60             selectsEnd
61         } = this.props; // Date Props
62         /* eslint-enable no-unused-vars */
63         let wrapperClassName =
64             type !== 'radio'
65                 ? 'validation-input-wrapper'
66                 : 'validation-radio-wrapper';
67         if (disabled) {
68             wrapperClassName += ' disabled';
69         }
70         return (
71             <div className={wrapperClassName}>
72                 <FormGroup
73                     className={classNames('form-group', [groupClassName], {
74                         required: isRequired,
75                         'has-error': !isValid
76                     })}>
77                     {label &&
78                         (type !== 'checkbox' && type !== 'radio') && (
79                             <label className="control-label">{label}</label>
80                         )}
81                     {type === 'text' && (
82                         <FormControl
83                             bsClass={'form-control input-options-other'}
84                             onChange={e => this.onChange(e)}
85                             disabled={isReadOnlyMode || Boolean(disabled)}
86                             onBlur={onBlur}
87                             onKeyDown={onKeyDown}
88                             value={value || ''}
89                             inputRef={input => (this.input = input)}
90                             type={type}
91                             data-test-id={this.props['data-test-id']}
92                         />
93                     )}
94                     {type === 'number' && (
95                         <FormControl
96                             bsClass={'form-control input-options-other'}
97                             onChange={e => this.onChange(e)}
98                             disabled={isReadOnlyMode || Boolean(disabled)}
99                             onBlur={onBlur}
100                             onKeyDown={onKeyDown}
101                             value={value !== undefined ? value : ''}
102                             inputRef={input => (this.input = input)}
103                             type={type}
104                             data-test-id={this.props['data-test-id']}
105                         />
106                     )}
107
108                     {type === 'textarea' && (
109                         <FormControl
110                             className="form-control input-options-other"
111                             disabled={isReadOnlyMode || Boolean(disabled)}
112                             value={value || ''}
113                             onBlur={onBlur}
114                             onKeyDown={onKeyDown}
115                             componentClass={type}
116                             onChange={e => this.onChange(e)}
117                             inputRef={input => (this.input = input)}
118                             data-test-id={this.props['data-test-id']}
119                         />
120                     )}
121
122                     {type === 'checkbox' && (
123                         <Checkbox
124                             className={classNames({
125                                 required: isRequired,
126                                 'has-error': !isValid
127                             })}
128                             onChange={e => this.onChangeCheckBox(e)}
129                             disabled={isReadOnlyMode || Boolean(disabled)}
130                             checked={checked}
131                             data-test-id={this.props['data-test-id']}>
132                             {label}
133                         </Checkbox>
134                     )}
135
136                     {type === 'radio' && (
137                         <Radio
138                             name={name}
139                             checked={checked}
140                             disabled={isReadOnlyMode || Boolean(disabled)}
141                             value={value}
142                             onChange={isChecked =>
143                                 this.onChangeRadio(isChecked)
144                             }
145                             inputRef={input => (this.input = input)}
146                             label={label}
147                             data-test-id={this.props['data-test-id']}
148                         />
149                     )}
150                     {type === 'select' && (
151                         <FormControl
152                             onClick={e => this.optionSelect(e)}
153                             className="custom-select"
154                             componentClass={type}
155                             inputRef={input => (this.input = input)}
156                             name={name}
157                             {...inputProps}
158                             data-test-id={this.props['data-test-id']}
159                         />
160                     )}
161                     {type === 'date' && (
162                         <Datepicker
163                             date={value}
164                             format={dateFormat}
165                             startDate={startDate}
166                             endDate={endDate}
167                             inputRef={input => (this.input = input)}
168                             onChange={this.props.onChange}
169                             disabled={isReadOnlyMode || Boolean(disabled)}
170                             data-test-id={this.props['data-test-id']}
171                             selectsStart={selectsStart}
172                             selectsEnd={selectsEnd}
173                         />
174                     )}
175                 </FormGroup>
176                 {this.renderErrorOverlay()}
177             </div>
178         );
179     }
180
181     getValue() {
182         return this.props.type !== 'select'
183             ? this.state.value
184             : this.state.selectedValues;
185     }
186
187     getChecked() {
188         return this.state.checked;
189     }
190
191     optionSelect(e) {
192         let selectedValues = [];
193         if (e.target.value) {
194             selectedValues.push(e.target.value);
195         }
196         this.setState({
197             selectedValues
198         });
199     }
200
201     static getDerivedStateFromProps(props, state) {
202         if (state.value === props.value) {
203             return null;
204         } else {
205             return { value: props.value, ...state };
206         }
207     }
208
209     onChange(e) {
210         const { onChange, type } = this.props;
211         let value = e.target.value;
212         if (type === 'number') {
213             if (value === '') {
214                 value = undefined;
215             } else {
216                 value = Number(value);
217             }
218         }
219         onChange(value);
220     }
221
222     onChangeCheckBox(e) {
223         let { onChange } = this.props;
224         let checked = e.target.checked;
225         this.setState({
226             checked
227         });
228         onChange(checked);
229     }
230
231     onChangeRadio(isChecked) {
232         let { onChange } = this.props;
233         this.setState({
234             checked: isChecked
235         });
236         onChange(this.state.value);
237     }
238
239     focus() {
240         ReactDOM.findDOMNode(this.input).focus();
241     }
242
243     renderErrorOverlay() {
244         let position = 'right';
245         const { errorText = '', isValid = true, type, overlayPos } = this.props;
246
247         if (overlayPos) {
248             position = overlayPos;
249         } else if (
250             type === 'text' ||
251             type === 'email' ||
252             type === 'number' ||
253             type === 'radio' ||
254             type === 'password' ||
255             type === 'date'
256         ) {
257             position = 'bottom';
258         }
259
260         return (
261             <Overlay
262                 show={!isValid}
263                 placement={position}
264                 target={() => {
265                     let target = ReactDOM.findDOMNode(this.input);
266                     return target.offsetParent ? target : undefined;
267                 }}
268                 container={this}>
269                 <Tooltip
270                     id={`error-${errorText.replace(' ', '-')}`}
271                     className="validation-error-message">
272                     {errorText}
273                 </Tooltip>
274             </Overlay>
275         );
276     }
277 }
278 export default Input;