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