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