UNPKG

fit-select

Version:

选择框

349 lines (322 loc) 15.5 kB
"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;