bb9d77760aa32aa81ab7b1871b4c07f7f73706b2
[aai/sparky-fe.git] / src / generic-components / input / inputOptions / InputOptions.jsx
1 /*
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017-2018 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 import React from 'react';
22 import { PropTypes } from 'prop-types';
23 import i18n from 'utils/i18n/i18n.js';
24 import classNames from 'classnames';
25 import Select from 'generic-components/input/SelectInput.jsx';
26
27 export const other = {OTHER: 'Other'};
28
29 class InputOptions extends React.Component {
30                 
31                 static propTypes = {
32                                 values: PropTypes.arrayOf(PropTypes.shape({
33                                                 enum: PropTypes.string,
34                                                 title: PropTypes.string
35                                 })),
36                                 isEnabledOther: PropTypes.bool,
37                                 title: PropTypes.string,
38                                 selectedValue: PropTypes.string,
39                                 multiSelectedEnum: PropTypes.array,
40                                 selectedEnum: PropTypes.string,
41                                 otherValue: PropTypes.string,
42                                 onEnumChange: PropTypes.func,
43                                 onOtherChange: PropTypes.func,
44                                 isRequired: PropTypes.bool,
45                                 isMultiSelect: PropTypes.bool
46                 };
47                 
48                 
49                 static contextTypes = {
50                                 isReadOnlyMode: PropTypes.bool
51                 };
52                 
53                 state = {
54                                 otherInputDisabled: !this.props.otherValue
55                 };
56                 
57                 oldProps = {
58                                 selectedEnum: '',
59                                 otherValue: '',
60                                 multiSelectedEnum: []
61                 };
62                 
63                 render() {
64                                 let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
65                                 
66                                 let currentMultiSelectedEnum = [];
67                                 let currentSelectedEnum = '';
68                                 let {otherInputDisabled} = this.state;
69                                 if (isMultiSelect) {
70                                                 currentMultiSelectedEnum = multiSelectedEnum;
71                                                 if (!otherInputDisabled) {
72                                                                 currentSelectedEnum =
73                                                                                 multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
74                                                 }
75                                 }
76                                 else {
77                                                 currentSelectedEnum = selectedEnum;
78                                 }
79                                 
80                                 let isReadOnlyMode = this.context.isReadOnlyMode;
81                                 
82                                 return (
83                                                 <div
84                                                                 className={classNames('form-group', {'required' : validations.required , 'has-error' : hasError})}>
85                                                                 <label className='control-label'>{label}</label>
86                                                                 {isMultiSelect && otherInputDisabled ?
87                                                                  <Select
88                                                                                  ref='_myInput'
89                                                                                  value={currentMultiSelectedEnum}
90                                                                                  className='options-input'
91                                                                                  clearable={false}
92                                                                                  required={isRequired}
93                                                                                  disabled={isReadOnlyMode || Boolean(this.props.disabled)}
94                                                                                  onBlur={() => onBlur()}
95                                                                                  onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
96                                                                                  options={this.renderMultiSelectOptions(values)}
97                                                                                  multi/> :
98                                                                  <div className={classNames('input-options',{'has-error' : hasError})}>
99                                                                                  <select
100                                                                                                  ref={'_myInput'}
101                                                                                                  label={label}
102                                                                                                  className='form-control input-options-select'
103                                                                                                  value={currentSelectedEnum}
104                                                                                                  style={{'width' : otherInputDisabled ? '100%' : '95px'}}
105                                                                                                  onBlur={() => onBlur()}
106                                                                                                  disabled={isReadOnlyMode || Boolean(this.props.disabled)}
107                                                                                                  onChange={ value => this.enumChanged(value)}
108                                                                                                  type='select'>
109                                                                                                  {values &&
110                                                                                                  values.length &&
111                                                                                                  values.map(val => this.renderOptions(val))}
112                                                                                                  {onOtherChange && <option key='other'
113                                                                                                                            value={other.OTHER}>{i18n(
114                                                                                                                  other.OTHER)}</option>}
115                                                                                                  {children}
116                                                                                  </select>
117                                                                                 
118                                                                                  {!otherInputDisabled && <div className='input-options-separator'/>}
119                                                                                  <input
120                                                                                                  className='form-control input-options-other'
121                                                                                                  placeholder={i18n('other')}
122                                                                                                  ref='_otherValue'
123                                                                                                  style={{'display' : otherInputDisabled ? 'none' : 'block'}}
124                                                                                                  disabled={isReadOnlyMode || Boolean(this.props.disabled)}
125                                                                                                  value={otherValue || ''}
126                                                                                                  onBlur={() => onBlur()}
127                                                                                                  onChange={() => this.changedOtherInput()}/>
128                                                                  </div>
129                                                                 }
130                                                 </div>
131                                 );
132                 }
133                 
134                 renderOptions(val) {
135                                 return (
136                                                 <option key={val.enum} value={val.enum}>{val.title}</option>
137                                 );
138                 }
139                 
140                 
141                 renderMultiSelectOptions(values) {
142                                 let {onOtherChange} = this.props;
143                                 let optionsList = [];
144                                 if (onOtherChange) {
145                                                 optionsList = values.map(option => {
146                                                                 return {
147                                                                                 label: option.title,
148                                                                                 value: option.enum,
149                                                                 };
150                                                 }).concat([{
151                                                                 label: i18n(other.OTHER),
152                                                                 value: i18n(other.OTHER),
153                                                 }]);
154                                 }
155                                 else {
156                                                 optionsList = values.map(option => {
157                                                                 return {
158                                                                                 label: option.title,
159                                                                                 value: option.enum,
160                                                                 };
161                                                 });
162                                 }
163                                 if (optionsList.length > 0 && optionsList[0].value === '') {
164                                                 optionsList.shift();
165                                 }
166                                 return optionsList;
167                 }
168                 
169                 getValue() {
170                                 let res = '';
171                                 let {isMultiSelect} = this.props;
172                                 let {otherInputDisabled} = this.state;
173                                 
174                                 if (otherInputDisabled) {
175                                                 res =
176                                                                 isMultiSelect
177                                                                                 ? this.refs._myInput.getValue()
178                                                                                 : this.refs._myInput.value;
179                                 } else {
180                                                 res = this.refs._otherValue.value;
181                                 }
182                                 return res;
183                 }
184                 
185                 enumChanged() {
186                                 let enumValue = this.refs._myInput.value;
187                                 let {onEnumChange, isMultiSelect, onChange} = this.props;
188                                 this.setState({
189                                                 otherInputDisabled: enumValue !== other.OTHER
190                                 });
191                                 if (onEnumChange) {
192                                                 onEnumChange(isMultiSelect ? [enumValue] : enumValue);
193                                 }
194                                 
195                                 if (onChange) {
196                                                 onChange(enumValue);
197                                 }
198                                 
199                 }
200                 
201                 multiSelectEnumChanged(enumValue) {
202                                 let {onEnumChange} = this.props;
203                                 let selectedValues = enumValue.map(enumVal => {
204                                                 return enumVal.value;
205                                 });
206                                 
207                                 if (this.state.otherInputDisabled === false) {
208                                                 selectedValues.shift();
209                                 }
210                                 else if (selectedValues.includes(i18n(other.OTHER))) {
211                                                 selectedValues = [i18n(other.OTHER)];
212                                 }
213                                 
214                                 this.setState({
215                                                 otherInputDisabled: !selectedValues.includes(i18n(other.OTHER))
216                                 });
217                                 onEnumChange(selectedValues);
218                 }
219                 
220                 changedOtherInput() {
221                                 let {onOtherChange} = this.props;
222                                 onOtherChange(this.refs._otherValue.value);
223                 }
224                 
225                 componentDidUpdate() {
226                                 let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
227                                 if (this.oldProps.otherValue !== otherValue
228                                                 || this.oldProps.selectedEnum !== selectedEnum
229                                                 || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
230                                                 this.oldProps = {
231                                                                 otherValue,
232                                                                 selectedEnum,
233                                                                 multiSelectedEnum
234                                                 };
235                                                 onInputChange();
236                                 }
237                 }
238                 
239 }
240
241 export default InputOptions;