react-form-controlled
Version:
Intuitive react forms for building powerful applications
161 lines (130 loc) • 3.96 kB
JavaScript
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