// External Dependencies import React, { PureComponent } from 'react'; import propTypes from 'prop-types'; import classnames from 'classnames'; import map from 'lodash/map'; import toString from 'lodash/toString'; import isUndefined from 'lodash/isUndefined'; import isArray from 'lodash/isArray'; import isEmpty from 'lodash/isEmpty'; import isObject from 'lodash/isObject'; import includes from 'lodash/includes'; import keys from 'lodash/keys'; import get from 'lodash/get'; import concat from 'lodash/concat'; import difference from 'lodash/difference'; import intersection from 'lodash/intersection'; // Internal Dependencies import ETCoreControlSelectOption from '../select-option/select-option'; import ETCoreControlSelectOptgroup from '../select-optgroup/select-optgroup'; import './select.scss'; class ETCoreControlSelect extends PureComponent { static propTypes = { name: propTypes.string.isRequired, } componentDidMount() { if (this.props.group_prop) { this.props._onChange(this.props.group_prop, this.getGroupForSelected()); } } getGroupForSelected = () => jQuery(this.node).find(':selected').parent().attr('label'); _onChange = event => { const attrName = this.props.name; const group = this.getGroupForSelected(); const overwriteOnchange = this.props.overwrite_onchange; const valueOverwrite = this.props.value_overwrite; let selectedValue = event.target.value; if (group) { if (get(this, 'props.parseGroupValue', true)){ selectedValue = `${group}|${selectedValue}`; } if (this.props.group_prop) { this.props._onChange(this.props.group_prop, group); } } this.props._onChange(attrName, selectedValue); // Updating other fields based on select's selected option, if the overwrite_onchange and value_overwrite attributes are set if (overwriteOnchange && isArray(overwriteOnchange) && valueOverwrite && isObject(valueOverwrite)) { map(this.props.overwrite_onchange, attr => { if (! isUndefined(valueOverwrite[selectedValue])) { this.props._onChange(attr, valueOverwrite[selectedValue]); } }); } }; _render_options(options, group = '') { let list = keys(options); const props = this.props; if (!isEmpty(props.order)) { // option keys in `list` are all strings, ensure the same happens in `order` const order = map(props.order, String); // keys that are in both arrays go first, `order` dictates the order // then we add any other option key that might me missing in `order` list = concat(intersection(order, list), difference(list, order)) } return map(list, key => { const option = get(options, key); let _key = key; if ('' !== group) { _key = `${group}-${key}`; } return ( ); }); } render() { let value = toString(this.props.value) ? this.props.value : this.props.default; let optionNodes; if (! includes(keys(this.props.options), value) && includes(keys(this.props.options), toString(value))) { value = toString(value); } // Classname const className = { 'et-core-control-select': true, 'et-fb-settings-option-select': true, }; if (this.props.className) { className[this.props.className] = true; } if (this.props.groups) { optionNodes = map(this.props.options, (options, group) => { return '0' === group ? this._render_options(options, group) : ( {this._render_options(options, group)} ); }); } else { optionNodes = this._render_options(this.props.options); } const additional_attrs = {}; if (this.props.readonly) { additional_attrs.disabled = true; } let { id } = this.props; if (! id) { id = `et-fb-${this.props.name}`; } return ( ); } } export default ETCoreControlSelect;