fit-select
Version:
选择框
349 lines (322 loc) • 15.5 kB
JavaScript
"use strict";
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var __assign = undefined && undefined.__assign || Object.assign || function (t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
}
return t;
};
var React = require('react');
var ReactDOM = require('react-dom');
var classNames = require('classnames');
var $ = require('jquery');
var _ = require('lodash');
var _module = require('./module');
var src_1 = require('fit-input');
var src_2 = require('fit-transmit-transparently');
var option_1 = require('../option');
var opt_group_1 = require('../opt-group');
require('./index.css');
var Select = function (_React$Component) {
_inherits(Select, _React$Component);
function Select(props) {
_classCallCheck(this, Select);
var _this = _possibleConstructorReturn(this, (Select.__proto__ || Object.getPrototypeOf(Select)).call(this, props));
_this.state = new _module.State();
return _this;
}
_createClass(Select, [{
key: 'componentWillMount',
value: function componentWillMount() {
var _this2 = this;
this.setState({
value: this.props.value !== '' ? this.props.value : this.props.defaultValue
});
// 点击document
this.handleDocumentClick = function (event) {
if (!_this2._isMounted) return;
if (!$.contains(_this2.dom, event.target)) {
_this2.setState({
open: false
});
}
};
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if ('value' in nextProps && nextProps.value !== null) {
this.setState({
value: nextProps.value
});
}
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
this._isMounted = true;
this.dom = ReactDOM.findDOMNode(this);
$(document).on('click', this.handleDocumentClick);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this._isMounted = false;
$(document).off('click', this.handleDocumentClick);
}
// 选择框点击
}, {
key: 'handleSelectClick',
value: function handleSelectClick() {
var _this3 = this;
this.setState({
open: !this.state.open
}, function () {
if (_this3.state.open) {
$(_this3.dom).find('#j-search').focus();
}
});
}
// 选择栏目点击
}, {
key: 'handleClick',
value: function handleClick(value, label, children) {
var _this4 = this;
var zIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
// 如果没有 children,说明是最后一级了
if (!children) {
var newValue = this.state.value;
var newCascader = this.state.cascader;
// 将此级后的所有级联元素删除
var deleteEndNumber = newCascader.length - zIndex + 1;
while (deleteEndNumber > 0) {
newCascader.pop();
deleteEndNumber = deleteEndNumber - 1;
}
if (zIndex === 1) {
// 如果是第一级级联,才设置 state.value
newValue = value;
this.firstLabelValue = label;
} else {
// 否则设置级联元素对应项的value
newCascader[zIndex - 2].value = value;
newCascader[zIndex - 2].labelValue = label;
}
this.setState({
cascader: newCascader
});
// 如果级联显示完整路径,修改 labelValue 的值
var labelValue = label;
if (this.props.cascaderFull) {
var labelValueArray = [this.firstLabelValue];
this.state.cascader.forEach(function (item) {
labelValueArray.push(item.labelValue);
});
labelValue = labelValueArray.join(' / ');
}
this.setState({
open: false,
value: newValue,
labelValue: labelValue
}, function () {
if (_this4.props.cascaderFull) {
// 级联显示完整路径
var pathArray = [_this4.state.value];
_this4.state.cascader.forEach(function (item) {
pathArray.push(item.value);
});
_this4.props.onChange(pathArray);
} else {
_this4.props.onChange(value);
}
});
} else {
// 有 children,说明还有级联, zIndex 表示级联层级,最外层是 1,那么第一层级联就是 2
var _newCascader = this.state.cascader;
if (zIndex === 1) {
// 如果是第一级级联,设置 state.value
this.firstLabelValue = label;
this.setState({
value: value
});
} else {
// 否则设置级联元素对应项的value
var _newCascader2 = this.state.cascader;
_newCascader2[zIndex - 2].value = value;
_newCascader2[zIndex - 2].labelValue = label;
this.setState({
cascader: _newCascader2
});
}
// 因为点击选项,但后面还有,因此没点完,将labelValue设置为空
this.setState({
labelValue: ''
});
// 在级联后追加
if (_newCascader.length = zIndex - 1) {
_newCascader.push({
value: '',
options: children
});
} else {
// 改写已有级联,删除后面的数组
_newCascader[zIndex - 1] = {
value: value,
options: children
};
// 先有级联层级比当前 zIndex 大多少,全都 pop 掉
var _deleteEndNumber = _newCascader.length - zIndex;
while (_deleteEndNumber > 0) {
_newCascader.pop();
_deleteEndNumber = _deleteEndNumber - 1;
}
}
this.setState({
cascader: _newCascader
});
}
}
// 搜索框改变
}, {
key: 'handleSearchChange',
value: function handleSearchChange(event) {
this.setState({
searchValue: event.target.value
});
}
/**
* 设置初始化labelValue
*/
}, {
key: 'handleSetLabelValue',
value: function handleSetLabelValue(labelValue) {
this.setState({
labelValue: labelValue
});
}
}, {
key: 'getOptionChildren',
value: function getOptionChildren() {
var _this5 = this;
var chosenDropStyle = {
display: this.state.open ? null : 'none',
left: 0
};
// 循环子元素,同时获取value,同时判断search
var Children = React.Children.map(this.props['children'], function (item, index) {
var active = false;
if (item.props.value === _this5.state.value) {
active = true;
}
if (_.isArray(item.props.children)) {
item.props.children.map(function (childItem) {
if (childItem.props.value === _this5.state.value) {
active = true;
}
});
}
return React.cloneElement(item, {
onClick: _this5.handleClick.bind(_this5),
key: index,
active: active,
setLabelValue: _this5.handleSetLabelValue.bind(_this5),
activeValue: _this5.state.value,
searchValue: _this5.state.searchValue
});
});
// 搜索框
var Search = null;
if (this.props.search) {
Search = React.createElement("div", { className: "chosen-search" }, React.createElement(src_1.default, { id: "j-search", className: "search-input", label: "", placeholder: "搜索..", autoComplete: "off", onChange: this.handleSearchChange.bind(this) }));
}
return React.createElement("div", { id: "j-chosen", className: "chosen-drop", style: chosenDropStyle }, Search, React.createElement("ul", { className: "chosen-results" }, Children));
}
}, {
key: 'getOptionChildrenByOptions',
value: function getOptionChildrenByOptions() {
var _this6 = this;
var chosenDropStyle = {
display: this.state.open ? null : 'none',
left: 0
};
var OptionChildren = this.props.options.map(function (item, index) {
return _this6.getOptionItemByType(item, index, _this6.state.value, 1);
});
// 追加渲染级联元素
var CascaderChildrens = this.state.cascader.map(function (item, index) {
var options = item.options.map(function (childrenItem, childrenItemIndex) {
return _this6.getOptionItemByType(childrenItem, childrenItemIndex, item.value, index + 2);
});
return React.createElement("ul", { key: index, className: "chosen-results" }, options);
});
return React.createElement("div", { id: "j-chosen", className: "chosen-drop", style: chosenDropStyle }, React.createElement("div", { className: "flex-option-container" }, React.createElement("ul", { className: "chosen-results" }, OptionChildren), CascaderChildrens));
}
/**
* 根据一个 Option 元素类型返回对应ReactElement
*/
}, {
key: 'getOptionItemByType',
value: function getOptionItemByType(item, key, activeValue) {
var _this7 = this;
var zIndex = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
if (item.groupValue) {
// 是一个分组
var GroupChildren = item.children.map(function (item, index) {
return _this7.getOptionItemByType(item, index, activeValue, zIndex);
});
return React.createElement(opt_group_1.default, { key: key, ignoreChildren: true, label: item.groupValue }, GroupChildren);
}
// option 元素
var active = false;
if (item.key === activeValue) {
active = true;
}
return React.createElement(option_1.default, { key: key, value: item.key, onClick: this.handleClick.bind(this), active: active, zIndex: zIndex, optChildren: item.children, setLabelValue: this.handleSetLabelValue.bind(this), activeValue: this.state.value, searchValue: this.state.searchValue }, item.value);
}
}, {
key: 'dropIconRender',
value: function dropIconRender() {
var classes = classNames({
'open': this.state.open,
'fit-select-drop': true
});
return React.createElement("i", { className: classes });
}
}, {
key: 'render',
value: function render() {
var _classNames;
var classes = classNames((_classNames = {
'fit-select': true
}, _defineProperty(_classNames, this.props['className'], !!this.props['className']), _defineProperty(_classNames, 'simple', this.props.simple), _classNames));
var renderChosen = void 0;
if (this.props.options.length === 0) {
renderChosen = this.getOptionChildren.call(this);
} else {
renderChosen = this.getOptionChildrenByOptions.call(this);
}
var extProps = {};
// 给精简模式用的额外字段
if (this.props.simple) {
extProps.label = '';
extProps.placeholder = '';
}
// 给搜索模式用的额外字段
if (this.props.search) {
extProps.highlightLine = false;
}
return React.createElement(src_1.default, __assign({}, src_2.others(new _module.Props(), this.props, ['children']), extProps, { onClick: this.handleSelectClick.bind(this), className: classes, value: this.state.labelValue, rightRender: this.dropIconRender.bind(this), innerRender: renderChosen }));
}
}]);
return Select;
}(React.Component);
Select.defaultProps = new _module.Props();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = Select;