blob: 3feb06da0ea375224005c5c3a1370af2980777f0 [file] [log] [blame]
svishnevb72a4b42018-05-24 15:52:14 +03001/*
2 * Copyright © 2016-2018 European Support Limited
AviZi280f8012017-06-09 02:39:56 +03003 *
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
Einav Weiss Keidar1801b242018-08-13 16:19:46 +03007 *
svishnevb72a4b42018-05-24 15:52:14 +03008 * http://www.apache.org/licenses/LICENSE-2.0
Einav Weiss Keidar1801b242018-08-13 16:19:46 +03009 *
AviZi280f8012017-06-09 02:39:56 +030010 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
svishnevb72a4b42018-05-24 15:52:14 +030012 * 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.
AviZi280f8012017-06-09 02:39:56 +030015 */
16import React from 'react';
17import ReactDOM from 'react-dom';
18import classNames from 'classnames';
19import Checkbox from 'react-bootstrap/lib/Checkbox.js';
Arielka51eac02019-07-07 12:56:11 +030020import { Radio } from 'onap-ui-react';
AviZi280f8012017-06-09 02:39:56 +030021import FormGroup from 'react-bootstrap/lib/FormGroup.js';
22import FormControl from 'react-bootstrap/lib/FormControl.js';
23import Overlay from 'react-bootstrap/lib/Overlay.js';
24import Tooltip from 'react-bootstrap/lib/Tooltip.js';
Avi Zivb8e2faf2017-07-18 19:45:38 +030025import Datepicker from 'nfvo-components/datepicker/Datepicker.jsx';
AviZi280f8012017-06-09 02:39:56 +030026
27class Input extends React.Component {
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020028 state = {
29 value: this.props.value,
30 checked: this.props.checked,
31 selectedValues: []
32 };
AviZi280f8012017-06-09 02:39:56 +030033
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020034 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']}
Vodafone804ec682019-03-18 15:46:53 +053092 placeholder={this.props.placeholder || ''}
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +020093 />
94 )}
95 {type === 'number' && (
96 <FormControl
97 bsClass={'form-control input-options-other'}
98 onChange={e => this.onChange(e)}
99 disabled={isReadOnlyMode || Boolean(disabled)}
100 onBlur={onBlur}
101 onKeyDown={onKeyDown}
102 value={value !== undefined ? value : ''}
103 inputRef={input => (this.input = input)}
104 type={type}
105 data-test-id={this.props['data-test-id']}
106 />
107 )}
atulpurohit8b346842019-11-05 14:31:56 +0530108 {type === 'file' && (
109 <FormControl
110 bsClass={'form-control input-options-other'}
111 onChange={e => this.onChangeFile(e)}
112 disabled={isReadOnlyMode || Boolean(disabled)}
113 type={type}
114 data-test-id={this.props['data-test-id']}
115 inputRef={input => (this.input = input)}
116 />
117 )}
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200118 {type === 'textarea' && (
119 <FormControl
120 className="form-control input-options-other"
121 disabled={isReadOnlyMode || Boolean(disabled)}
122 value={value || ''}
123 onBlur={onBlur}
124 onKeyDown={onKeyDown}
125 componentClass={type}
126 onChange={e => this.onChange(e)}
127 inputRef={input => (this.input = input)}
128 data-test-id={this.props['data-test-id']}
129 />
130 )}
AviZi280f8012017-06-09 02:39:56 +0300131
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200132 {type === 'checkbox' && (
133 <Checkbox
134 className={classNames({
135 required: isRequired,
136 'has-error': !isValid
137 })}
138 onChange={e => this.onChangeCheckBox(e)}
139 disabled={isReadOnlyMode || Boolean(disabled)}
140 checked={checked}
141 data-test-id={this.props['data-test-id']}>
142 {label}
143 </Checkbox>
144 )}
AviZi280f8012017-06-09 02:39:56 +0300145
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200146 {type === 'radio' && (
147 <Radio
148 name={name}
149 checked={checked}
150 disabled={isReadOnlyMode || Boolean(disabled)}
151 value={value}
152 onChange={isChecked =>
153 this.onChangeRadio(isChecked)
154 }
155 inputRef={input => (this.input = input)}
156 label={label}
157 data-test-id={this.props['data-test-id']}
158 />
159 )}
160 {type === 'select' && (
161 <FormControl
162 onClick={e => this.optionSelect(e)}
163 className="custom-select"
164 componentClass={type}
165 inputRef={input => (this.input = input)}
166 name={name}
167 {...inputProps}
168 data-test-id={this.props['data-test-id']}
169 />
170 )}
171 {type === 'date' && (
172 <Datepicker
173 date={value}
174 format={dateFormat}
175 startDate={startDate}
176 endDate={endDate}
177 inputRef={input => (this.input = input)}
178 onChange={this.props.onChange}
179 disabled={isReadOnlyMode || Boolean(disabled)}
180 data-test-id={this.props['data-test-id']}
181 selectsStart={selectsStart}
182 selectsEnd={selectsEnd}
183 />
184 )}
185 </FormGroup>
186 {this.renderErrorOverlay()}
187 </div>
188 );
189 }
AviZi280f8012017-06-09 02:39:56 +0300190
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200191 getValue() {
192 return this.props.type !== 'select'
193 ? this.state.value
194 : this.state.selectedValues;
195 }
AviZi280f8012017-06-09 02:39:56 +0300196
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200197 getChecked() {
198 return this.state.checked;
199 }
AviZi280f8012017-06-09 02:39:56 +0300200
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200201 optionSelect(e) {
202 let selectedValues = [];
203 if (e.target.value) {
204 selectedValues.push(e.target.value);
205 }
206 this.setState({
207 selectedValues
208 });
209 }
Einav Weiss Keidar1801b242018-08-13 16:19:46 +0300210
211 static getDerivedStateFromProps(props, state) {
212 if (state.value === props.value) {
213 return null;
214 } else {
215 return { value: props.value, ...state };
216 }
svishnevb72a4b42018-05-24 15:52:14 +0300217 }
Einav Weiss Keidar1801b242018-08-13 16:19:46 +0300218
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200219 onChange(e) {
220 const { onChange, type } = this.props;
221 let value = e.target.value;
222 if (type === 'number') {
223 if (value === '') {
224 value = undefined;
225 } else {
226 value = Number(value);
227 }
228 }
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200229 onChange(value);
230 }
AviZi280f8012017-06-09 02:39:56 +0300231
atulpurohit8b346842019-11-05 14:31:56 +0530232 onChangeFile(e) {
233 let { onChange } = this.props;
234 onChange(e.target.files[0]);
235 }
236
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200237 onChangeCheckBox(e) {
238 let { onChange } = this.props;
239 let checked = e.target.checked;
240 this.setState({
241 checked
242 });
243 onChange(checked);
244 }
AviZi280f8012017-06-09 02:39:56 +0300245
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200246 onChangeRadio(isChecked) {
247 let { onChange } = this.props;
248 this.setState({
249 checked: isChecked
250 });
251 onChange(this.state.value);
252 }
AviZi280f8012017-06-09 02:39:56 +0300253
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200254 focus() {
255 ReactDOM.findDOMNode(this.input).focus();
256 }
AviZi280f8012017-06-09 02:39:56 +0300257
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200258 renderErrorOverlay() {
259 let position = 'right';
260 const { errorText = '', isValid = true, type, overlayPos } = this.props;
AviZi280f8012017-06-09 02:39:56 +0300261
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200262 if (overlayPos) {
263 position = overlayPos;
264 } else if (
265 type === 'text' ||
266 type === 'email' ||
267 type === 'number' ||
268 type === 'radio' ||
269 type === 'password' ||
270 type === 'date'
271 ) {
272 position = 'bottom';
273 }
AviZi280f8012017-06-09 02:39:56 +0300274
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200275 return (
276 <Overlay
277 show={!isValid}
278 placement={position}
279 target={() => {
280 let target = ReactDOM.findDOMNode(this.input);
281 return target.offsetParent ? target : undefined;
282 }}
283 container={this}>
284 <Tooltip
285 id={`error-${errorText.replace(' ', '-')}`}
286 className="validation-error-message">
287 {errorText}
288 </Tooltip>
289 </Overlay>
290 );
291 }
AviZi280f8012017-06-09 02:39:56 +0300292}
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200293export default Input;