61bc33f0d80762834eb053d5ee6ba0b17a56f3c1
[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 i18n from 'utils/i18n/i18n.js';
23 import classNames from 'classnames';
24 import Select from 'generic-components/input/SelectInput.jsx';
25
26 export const other = {OTHER: 'Other'};
27
28 class InputOptions extends React.Component {
29                 
30                 static propTypes = {
31                                 values: React.PropTypes.arrayOf(React.PropTypes.shape({
32                                                 enum: React.PropTypes.string,
33                                                 title: React.PropTypes.string
34                                 })),
35                                 isEnabledOther: React.PropTypes.bool,
36                                 title: React.PropTypes.string,
37                                 selectedValue: React.PropTypes.string,
38                                 multiSelectedEnum: React.PropTypes.array,
39                                 selectedEnum: React.PropTypes.string,
40                                 otherValue: React.PropTypes.string,
41                                 onEnumChange: React.PropTypes.func,
42                                 onOtherChange: React.PropTypes.func,
43                                 isRequired: React.PropTypes.bool,
44                                 isMultiSelect: React.PropTypes.bool
45                 };
46                 
47                 
48                 static contextTypes = {
49                                 isReadOnlyMode: React.PropTypes.bool
50                 };
51                 
52                 state = {
53                                 otherInputDisabled: !this.props.otherValue
54                 };
55                 
56                 oldProps = {
57                                 selectedEnum: '',
58                                 otherValue: '',
59                                 multiSelectedEnum: []
60                 };
61                 
62                 render() {
63                                 let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
64                                 
65                                 let currentMultiSelectedEnum = [];
66                                 let currentSelectedEnum = '';
67                                 let {otherInputDisabled} = this.state;
68                                 if (isMultiSelect) {
69                                                 currentMultiSelectedEnum = multiSelectedEnum;
70                                                 if (!otherInputDisabled) {
71                                                                 currentSelectedEnum =
72                                                                                 multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
73                                                 }
74                                 }
75                                 else {
76                                                 currentSelectedEnum = selectedEnum;
77                                 }
78                                 
79                                 let isReadOnlyMode = this.context.isReadOnlyMode;
80                                 
81                                 return (
82                                                 <div
83                                                                 className={classNames('form-group', {'required' : validations.required , 'has-error' : hasError})}>
84                                                                 <label className='control-label'>{label}</label>
85                                                                 {isMultiSelect && otherInputDisabled ?
86                                                                  <Select
87                                                                                  ref='_myInput'
88                                                                                  value={currentMultiSelectedEnum}
89                                                                                  className='options-input'
90                                                                                  clearable={false}
91                                                                                  required={isRequired}
92                                                                                  disabled={isReadOnlyMode || Boolean(this.props.disabled)}
93                                                                                  onBlur={() => onBlur()}
94                                                                                  onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
95                                                                                  options={this.renderMultiSelectOptions(values)}
96                                                                                  multi/> :
97                                                                  <div className={classNames('input-options',{'has-error' : hasError})}>
98                                                                                  <select
99                                                                                                  ref={'_myInput'}
100                                                                                                  label={label}
101                                                                                                  className='form-control input-options-select'
102                                                                                                  value={currentSelectedEnum}
103                                                                                                  style={{'width' : otherInputDisabled ? '100%' : '95px'}}
104                                                                                                  onBlur={() => onBlur()}
105                                                                                                  disabled={isReadOnlyMode || Boolean(this.props.disabled)}
106                                                                                                  onChange={ value => this.enumChanged(value)}
107                                                                                                  type='select'>
108                                                                                                  {values &&
109                                                                                                  values.length &&
110                                                                                                  values.map(val => this.renderOptions(val))}
111                                                                                                  {onOtherChange && <option key='other'
112                                                                                                                            value={other.OTHER}>{i18n(
113                                                                                                                  other.OTHER)}</option>}
114                                                                                                  {children}
115                                                                                  </select>
116                                                                                 
117                                                                                  {!otherInputDisabled && <div className='input-options-separator'/>}
118                                                                                  <input
119                                                                                                  className='form-control input-options-other'
120                                                                                                  placeholder={i18n('other')}
121                                                                                                  ref='_otherValue'
122                                                                                                  style={{'display' : otherInputDisabled ? 'none' : 'block'}}
123                                                                                                  disabled={isReadOnlyMode || Boolean(this.props.disabled)}
124                                                                                                  value={otherValue || ''}
125                                                                                                  onBlur={() => onBlur()}
126                                                                                                  onChange={() => this.changedOtherInput()}/>
127                                                                  </div>
128                                                                 }
129                                                 </div>
130                                 );
131                 }
132                 
133                 renderOptions(val) {
134                                 return (
135                                                 <option key={val.enum} value={val.enum}>{val.title}</option>
136                                 );
137                 }
138                 
139                 
140                 renderMultiSelectOptions(values) {
141                                 let {onOtherChange} = this.props;
142                                 let optionsList = [];
143                                 if (onOtherChange) {
144                                                 optionsList = values.map(option => {
145                                                                 return {
146                                                                                 label: option.title,
147                                                                                 value: option.enum,
148                                                                 };
149                                                 }).concat([{
150                                                                 label: i18n(other.OTHER),
151                                                                 value: i18n(other.OTHER),
152                                                 }]);
153                                 }
154                                 else {
155                                                 optionsList = values.map(option => {
156                                                                 return {
157                                                                                 label: option.title,
158                                                                                 value: option.enum,
159                                                                 };
160                                                 });
161                                 }
162                                 if (optionsList.length > 0 && optionsList[0].value === '') {
163                                                 optionsList.shift();
164                                 }
165                                 return optionsList;
166                 }
167                 
168                 getValue() {
169                                 let res = '';
170                                 let {isMultiSelect} = this.props;
171                                 let {otherInputDisabled} = this.state;
172                                 
173                                 if (otherInputDisabled) {
174                                                 res =
175                                                                 isMultiSelect
176                                                                                 ? this.refs._myInput.getValue()
177                                                                                 : this.refs._myInput.value;
178                                 } else {
179                                                 res = this.refs._otherValue.value;
180                                 }
181                                 return res;
182                 }
183                 
184                 enumChanged() {
185                                 let enumValue = this.refs._myInput.value;
186                                 let {onEnumChange, isMultiSelect, onChange} = this.props;
187                                 this.setState({
188                                                 otherInputDisabled: enumValue !== other.OTHER
189                                 });
190                                 if (onEnumChange) {
191                                                 onEnumChange(isMultiSelect ? [enumValue] : enumValue);
192                                 }
193                                 
194                                 if (onChange) {
195                                                 onChange(enumValue);
196                                 }
197                                 
198                 }
199                 
200                 multiSelectEnumChanged(enumValue) {
201                                 let {onEnumChange} = this.props;
202                                 let selectedValues = enumValue.map(enumVal => {
203                                                 return enumVal.value;
204                                 });
205                                 
206                                 if (this.state.otherInputDisabled === false) {
207                                                 selectedValues.shift();
208                                 }
209                                 else if (selectedValues.includes(i18n(other.OTHER))) {
210                                                 selectedValues = [i18n(other.OTHER)];
211                                 }
212                                 
213                                 this.setState({
214                                                 otherInputDisabled: !selectedValues.includes(i18n(other.OTHER))
215                                 });
216                                 onEnumChange(selectedValues);
217                 }
218                 
219                 changedOtherInput() {
220                                 let {onOtherChange} = this.props;
221                                 onOtherChange(this.refs._otherValue.value);
222                 }
223                 
224                 componentDidUpdate() {
225                                 let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
226                                 if (this.oldProps.otherValue !== otherValue
227                                                 || this.oldProps.selectedEnum !== selectedEnum
228                                                 || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
229                                                 this.oldProps = {
230                                                                 otherValue,
231                                                                 selectedEnum,
232                                                                 multiSelectedEnum
233                                                 };
234                                                 onInputChange();
235                                 }
236                 }
237                 
238 }
239
240 export default InputOptions;