Add collaboration feature
[sdc.git] / openecomp-ui / src / nfvo-components / input / validation / Input.jsx
1 /*!
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  */
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
29         state = {
30                 value: this.props.value,
31                 checked: this.props.checked,
32                 selectedValues: []
33         };
34
35         render() {
36                 const {label, isReadOnlyMode, value, onBlur, onKeyDown, type, disabled, checked, name} = this.props;
37                 // eslint-disable-next-line no-unused-vars
38                 const {groupClassName, isValid = true, errorText, isRequired,  overlayPos, ...inputProps} = this.props;
39                 const {dateFormat, startDate, endDate, selectsStart, selectsEnd} = this.props; // Date Props
40                 let wrapperClassName = (type !== 'radio') ? 'validation-input-wrapper' : 'validation-radio-wrapper';
41                 if (disabled) {
42                         wrapperClassName += ' disabled';
43                 }
44                 return(
45                         <div className={wrapperClassName}>
46                                 <FormGroup className={classNames('form-group', [groupClassName], {'required' : isRequired , 'has-error' : !isValid})} >
47                                         {(label && (type !== 'checkbox' && type !== 'radio')) && <label className='control-label'>{label}</label>}
48                                         {type === 'text'  &&
49                                         <FormControl
50                                                 bsClass={'form-control input-options-other'}
51                                                 onChange={(e) => this.onChange(e)}
52                                                 disabled={isReadOnlyMode || Boolean(disabled)}
53                                                 onBlur={onBlur}
54                                                 onKeyDown={onKeyDown}
55                                                 value={value || ''}
56                                                 inputRef={(input) => this.input = input}
57                                                 type={type}
58                                                 data-test-id={this.props['data-test-id']}/>}
59                                         {type === 'number' &&
60                                         <FormControl
61                                                 bsClass={'form-control input-options-other'}
62                                                 onChange={(e) => this.onChange(e)}
63                                                 disabled={isReadOnlyMode || Boolean(disabled)}
64                                                 onBlur={onBlur}
65                                                 onKeyDown={onKeyDown}
66                                                 value={(value !== undefined) ? value : ''}
67                                                 inputRef={(input) => this.input = input}
68                                                 type={type}
69                                                 data-test-id={this.props['data-test-id']}/>}
70
71                                         {type === 'textarea' &&
72                                         <FormControl
73                                                 className='form-control input-options-other'
74                                                 disabled={isReadOnlyMode || Boolean(disabled)}
75                                                 value={value || ''}
76                                                 onBlur={onBlur}
77                                                 onKeyDown={onKeyDown}
78                                                 componentClass={type}
79                                                 onChange={(e) => this.onChange(e)}
80                                                 inputRef={(input) => this.input = input}
81                                                 data-test-id={this.props['data-test-id']}/>}
82
83                                         {type === 'checkbox' &&
84                                         <Checkbox
85                                                 className={classNames({'required' : isRequired , 'has-error' : !isValid})}
86                                                 onChange={(e)=>this.onChangeCheckBox(e)}
87                                                 disabled={isReadOnlyMode || Boolean(disabled)}
88                                                 checked={checked}
89                                                 data-test-id={this.props['data-test-id']}>{label}</Checkbox>}
90
91                                         {type === 'radio' &&
92                                         <Radio name={name}
93                                                    checked={checked}
94                                                    disabled={isReadOnlyMode || Boolean(disabled)}
95                                                    value={value}
96                                                 onChange={(isChecked)=>this.onChangeRadio(isChecked)}
97                                                    inputRef={(input) => this.input = input}
98                                                 label={label}
99                                                 data-test-id={this.props['data-test-id']} />}
100                                         {type === 'select' &&
101                                         <FormControl onClick={ (e) => this.optionSelect(e) }
102                                                  componentClass={type}
103                                                  inputRef={(input) => this.input = input}
104                                                  name={name} {...inputProps}
105                                                  data-test-id={this.props['data-test-id']}/>}
106                                         {type === 'date' && 
107                                         <Datepicker 
108                                                 date={value}
109                                                 format={dateFormat}
110                                                 startDate={startDate}
111                                                 endDate={endDate}
112                                                 inputRef={(input) => this.input = input}
113                                                 onChange={this.props.onChange}
114                                                 disabled={isReadOnlyMode || Boolean(disabled)}
115                                                 data-test-id={this.props['data-test-id']}
116                                                 selectsStart={selectsStart}
117                                                 selectsEnd={selectsEnd} />}
118                                 </FormGroup>
119                                 { this.renderErrorOverlay() }
120                         </div>
121                 );
122         }
123
124         getValue() {
125                 return this.props.type !== 'select' ? this.state.value : this.state.selectedValues;
126         }
127
128         getChecked() {
129                 return this.state.checked;
130         }
131
132         optionSelect(e) {
133                 let selectedValues = [];
134                 if (e.target.value) {
135                         selectedValues.push(e.target.value);
136                 }
137                 this.setState({
138                         selectedValues
139                 });
140         }
141
142         onChange(e) {
143                 const {onChange, type} = this.props;
144                 let value = e.target.value;
145                 if (type === 'number') {
146                         if (value === '') {
147                                 value = undefined;
148                         } else {
149                                 value = Number(value);
150                         }
151                 }
152                 this.setState({
153                         value
154                 });
155                 onChange(value);
156         }
157
158         onChangeCheckBox(e) {
159                 let {onChange} = this.props;
160                 let checked = e.target.checked;
161                 this.setState({
162                         checked
163                 });
164                 onChange(checked);
165         }
166
167         onChangeRadio(isChecked) {
168                 let {onChange} = this.props;
169                 this.setState({
170                         checked: isChecked
171                 });
172                 onChange(this.state.value);
173         }
174
175         focus() {
176                 ReactDOM.findDOMNode(this.input).focus();
177         }
178
179         renderErrorOverlay() {
180                 let position = 'right';
181                 const {errorText = '', isValid = true, type, overlayPos} = this.props;
182
183                 if (overlayPos) {
184                         position = overlayPos;
185                 }
186                 else if (type === 'text'
187                         || type === 'email'
188                         || type === 'number'
189                         || type === 'radio'
190                         || type === 'password'
191                         || type === 'date') {
192                         position = 'bottom';
193                 }
194
195                 return (
196                         <Overlay
197                                 show={!isValid}
198                                 placement={position}
199                                 target={() => {
200                                         let target = ReactDOM.findDOMNode(this.input);
201                                         return target.offsetParent ? target : undefined;
202                                 }}
203                                 container={this}>
204                                 <Tooltip
205                                         id={`error-${errorText.replace(' ', '-')}`}
206                                         className='validation-error-message'>
207                                         {errorText}
208                                 </Tooltip>
209                         </Overlay>
210                 );
211         }
212
213 }
214 export default  Input;