blob: a5d6f4fd7a812b72c61c383e387a43abd1882f3e [file] [log] [blame]
AviZi280f8012017-06-09 02:39:56 +03001/*!
2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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
13 * or implied. See the License for the specific language governing
14 * permissions and limitations under the License.
15 */
16import React from 'react';
17import ReactDOM from 'react-dom';
18import classNames from 'classnames';
19import Checkbox from 'react-bootstrap/lib/Checkbox.js';
talig8e9c0652017-12-20 14:30:43 +020020import Radio from 'sdc-ui/lib/react/Radio.js';
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']}
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 )}
AviZi280f8012017-06-09 02:39:56 +0300107
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200108 {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 )}
AviZi280f8012017-06-09 02:39:56 +0300121
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200122 {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 )}
AviZi280f8012017-06-09 02:39:56 +0300135
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200136 {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 }
AviZi280f8012017-06-09 02:39:56 +0300180
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200181 getValue() {
182 return this.props.type !== 'select'
183 ? this.state.value
184 : this.state.selectedValues;
185 }
AviZi280f8012017-06-09 02:39:56 +0300186
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200187 getChecked() {
188 return this.state.checked;
189 }
AviZi280f8012017-06-09 02:39:56 +0300190
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200191 optionSelect(e) {
192 let selectedValues = [];
193 if (e.target.value) {
194 selectedValues.push(e.target.value);
195 }
196 this.setState({
197 selectedValues
198 });
199 }
AviZi280f8012017-06-09 02:39:56 +0300200
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200201 onChange(e) {
202 const { onChange, type } = this.props;
203 let value = e.target.value;
204 if (type === 'number') {
205 if (value === '') {
206 value = undefined;
207 } else {
208 value = Number(value);
209 }
210 }
211 this.setState({
212 value
213 });
214 onChange(value);
215 }
AviZi280f8012017-06-09 02:39:56 +0300216
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200217 onChangeCheckBox(e) {
218 let { onChange } = this.props;
219 let checked = e.target.checked;
220 this.setState({
221 checked
222 });
223 onChange(checked);
224 }
AviZi280f8012017-06-09 02:39:56 +0300225
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200226 onChangeRadio(isChecked) {
227 let { onChange } = this.props;
228 this.setState({
229 checked: isChecked
230 });
231 onChange(this.state.value);
232 }
AviZi280f8012017-06-09 02:39:56 +0300233
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200234 focus() {
235 ReactDOM.findDOMNode(this.input).focus();
236 }
AviZi280f8012017-06-09 02:39:56 +0300237
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200238 renderErrorOverlay() {
239 let position = 'right';
240 const { errorText = '', isValid = true, type, overlayPos } = this.props;
AviZi280f8012017-06-09 02:39:56 +0300241
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200242 if (overlayPos) {
243 position = overlayPos;
244 } else if (
245 type === 'text' ||
246 type === 'email' ||
247 type === 'number' ||
248 type === 'radio' ||
249 type === 'password' ||
250 type === 'date'
251 ) {
252 position = 'bottom';
253 }
AviZi280f8012017-06-09 02:39:56 +0300254
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200255 return (
256 <Overlay
257 show={!isValid}
258 placement={position}
259 target={() => {
260 let target = ReactDOM.findDOMNode(this.input);
261 return target.offsetParent ? target : undefined;
262 }}
263 container={this}>
264 <Tooltip
265 id={`error-${errorText.replace(' ', '-')}`}
266 className="validation-error-message">
267 {errorText}
268 </Tooltip>
269 </Overlay>
270 );
271 }
AviZi280f8012017-06-09 02:39:56 +0300272}
Einav Weiss Keidar7fdf7332018-03-20 14:45:40 +0200273export default Input;