2 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 import React from 'react';
17 import i18n from 'nfvo-utils/i18n/i18n.js';
18 import classNames from 'classnames';
19 import Select from 'nfvo-components/input/SelectInput.jsx';
21 export const other = {OTHER: 'Other'};
23 class InputOptions extends React.Component {
26 values: React.PropTypes.arrayOf(React.PropTypes.shape({
27 enum: React.PropTypes.string,
28 title: React.PropTypes.string
30 isEnabledOther: React.PropTypes.bool,
31 label: React.PropTypes.string,
32 selectedValue: React.PropTypes.string,
33 multiSelectedEnum: React.PropTypes.oneOfType([
34 React.PropTypes.string,
37 selectedEnum: React.PropTypes.string,
38 otherValue: React.PropTypes.string,
39 onEnumChange: React.PropTypes.func,
40 onOtherChange: React.PropTypes.func,
41 onBlur: React.PropTypes.func,
42 isRequired: React.PropTypes.bool,
43 isMultiSelect: React.PropTypes.bool,
44 hasError: React.PropTypes.bool,
45 disabled: React.PropTypes.bool
49 static contextTypes = {
50 isReadOnlyMode: React.PropTypes.bool
54 otherInputDisabled: !this.props.otherValue
64 let {label, isRequired, values, otherValue, onOtherChange, isMultiSelect, onBlur, multiSelectedEnum, selectedEnum, hasError, validations, children} = this.props;
65 const dataTestId = this.props['data-test-id'] ? {'data-test-id': this.props['data-test-id']} : {};
66 let currentMultiSelectedEnum = [];
67 let currentSelectedEnum = '';
68 let {otherInputDisabled} = this.state;
70 currentMultiSelectedEnum = multiSelectedEnum;
71 if(!otherInputDisabled) {
72 currentSelectedEnum = multiSelectedEnum ? multiSelectedEnum.toString() : undefined;
75 else if(selectedEnum){
76 currentSelectedEnum = selectedEnum;
82 let isReadOnlyMode = this.context.isReadOnlyMode;
85 <div className={classNames('form-group', {'required' : (validations && validations.required) || isRequired, 'has-error' : hasError})}>
86 {label && <label className='control-label'>{label}</label>}
87 {isMultiSelect && otherInputDisabled ?
91 value={currentMultiSelectedEnum}
92 className='options-input'
95 disabled={isReadOnlyMode || Boolean(this.props.disabled)}
96 onBlur={() => onBlur()}
97 onMultiSelectChanged={value => this.multiSelectEnumChanged(value)}
98 options={this.renderMultiSelectOptions(values)}
100 <div className={classNames('input-options',{'has-error' : hasError})}>
105 className='form-control input-options-select'
106 value={currentSelectedEnum}
107 style={{'width' : otherInputDisabled ? '100%' : '100px'}}
108 onBlur={() => onBlur()}
109 disabled={isReadOnlyMode || Boolean(this.props.disabled)}
110 onChange={ value => this.enumChanged(value)}
112 {children || (values && values.length && values.map((val, index) => this.renderOptions(val, index)))}
113 {onOtherChange && <option key='other' value={other.OTHER}>{i18n(other.OTHER)}</option>}
116 {!otherInputDisabled && <div className='input-options-separator'/>}
118 className='form-control input-options-other'
119 placeholder={i18n('other')}
121 style={{'display' : otherInputDisabled ? 'none' : 'block'}}
122 disabled={isReadOnlyMode || Boolean(this.props.disabled)}
123 value={otherValue || ''}
124 onBlur={() => onBlur()}
125 onChange={() => this.changedOtherInput()}/>
132 renderOptions(val, index){
134 <option key={index} value={val.enum}>{val.title}</option>
139 renderMultiSelectOptions(values) {
140 let {onOtherChange} = this.props;
141 let optionsList = [];
143 optionsList = values.map(option => {
149 label: i18n(other.OTHER),
150 value: i18n(other.OTHER),
154 optionsList = values.map(option => {
161 if (optionsList.length > 0 && optionsList[0].value === '') {
169 let {isMultiSelect} = this.props;
170 let {otherInputDisabled} = this.state;
172 if (otherInputDisabled) {
173 res = isMultiSelect ? this.refs._myInput.getValue() : this.refs._myInput.value;
175 res = this.refs._otherValue.value;
181 let enumValue = this.refs._myInput.value;
182 let {onEnumChange, onOtherChange, isMultiSelect, onChange} = this.props;
184 otherInputDisabled: !Boolean(onOtherChange) || enumValue !== other.OTHER
187 let value = isMultiSelect ? [enumValue] : enumValue;
196 multiSelectEnumChanged(enumValue) {
197 let {onEnumChange, onOtherChange} = this.props;
198 let selectedValues = enumValue.map(enumVal => {
199 return enumVal.value;
202 if (this.state.otherInputDisabled === false) {
203 selectedValues.shift();
205 else if (selectedValues.includes(i18n(other.OTHER))) {
206 selectedValues = [i18n(other.OTHER)];
210 otherInputDisabled: !Boolean(onOtherChange) || !selectedValues.includes(i18n(other.OTHER))
212 onEnumChange(selectedValues);
215 changedOtherInput() {
216 let {onOtherChange} = this.props;
217 onOtherChange(this.refs._otherValue.value);
220 componentDidUpdate() {
221 let {otherValue, selectedEnum, onInputChange, multiSelectedEnum} = this.props;
222 if (this.oldProps.otherValue !== otherValue
223 || this.oldProps.selectedEnum !== selectedEnum
224 || this.oldProps.multiSelectedEnum !== multiSelectedEnum) {
234 static getTitleByName(values, name) {
235 for (let key of Object.keys(values)) {
236 let option = values[key].find(option => option.enum === name);
246 export default InputOptions;