UNPKG

react-form-controlled

Version:

Intuitive react forms for building powerful applications

161 lines (130 loc) 3.96 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; import isPlainObject from 'lodash/isPlainObject'; import React from 'react'; import PropTypes from 'prop-types'; import Element from './Element'; const PLACEHOLDER_VALUE = ''; // null and undefined is uncontrolled value export default class Select extends Element { constructor(props, context) { super(props, context); this.onChange = evn => { evn.stopPropagation(); const nodes = evn.target.options || []; const options = this.state.options; const values = []; for (let index = 0; index < nodes.length; index++) { const node = nodes[index]; if (!node.selected) { continue; } const optionValue = node.value; if (typeof optionValue === 'undefined' || !optionValue.length) { continue; } const optionIndex = Number(optionValue); if (!options[optionIndex]) { continue; } values.push(options[optionIndex].value); } const isMultiple = this.isMultiple(); this.setValue(isMultiple ? values : values[0]); const { onChange } = this.props; if (typeof onChange === 'function') { onChange(evn); } }; this.state = { options: this.prepareOptions(props.options) }; } componentWillReceiveProps(props) { this.setState({ options: this.prepareOptions(props.options) }); } prepareOptions(options) { const selectOptions = []; if (isPlainObject(options)) { Object.keys(options).forEach(key => { selectOptions.push({ value: key, label: options[key] }); }); } else if (Array.isArray(options)) { options.forEach(option => { const isObject = isPlainObject(option); selectOptions.push({ value: isObject ? option.value : option, label: isObject ? option.label : option }); }); } return selectOptions; } getValues() { const { options } = this.state; const value = this.getValue(); const { placeholder } = this.props; const isMultiple = this.isMultiple(); const values = []; options.forEach((option, pos) => { if (!isMultiple && option.value === value) { values.push(pos); } else if (isMultiple && value && value.length && value.indexOf(option.value) !== -1) { values.push(pos); } }); if (!values.length && placeholder) { values.unshift(PLACEHOLDER_VALUE); } return isMultiple ? values : values[0]; } renderPlaceholder() { const { placeholder } = this.props; if (typeof placeholder === 'undefined') { return null; } return React.createElement( 'option', { value: PLACEHOLDER_VALUE }, placeholder ); } isMultiple() { return !!this.props.multi || !!this.props.multiple; } getClassName() { const { className } = this.props; return className; } render() { const { options } = this.state; const { path, disabled, required } = this.props; const values = this.getValues(); return React.createElement( 'select', { name: path, value: values, className: this.getClassName(), disabled: disabled, required: required, multiple: this.isMultiple(), onChange: this.onChange }, this.renderPlaceholder(), options.map((option, pos) => React.createElement( 'option', { value: pos, key: pos }, option.label )) ); } } Select.propTypes = _extends({}, Element.propTypes, { disabled: PropTypes.bool, className: PropTypes.string }); //# sourceMappingURL=Select.js.map