UNPKG

@beisen/dropdown-list

Version:

DropDownList

298 lines (286 loc) 11.2 kB
import React, {Component} from 'react' import {findDOMNode} from 'react-dom'; import CommonMount from '@beisen/common-mount'; import InputBox from "@beisen/input-box" import DropDown from "@beisen/dropdown" import "../src/style/index.scss" const defaultTranslation = { pleaseSearchText: '请搜索', confirmText: '确定', pleaseSelect: '请选择', emptyBgText: '这里什么都没有...' }; class DropDownList extends Component { static defaultProps = { showPanel: true, hasSearch: true, limitCount: 999999, PromptMsg: "" } constructor(props) { super(props); this.translation = Object.assign({}, defaultTranslation, props.translation); this.state = { defaultValue: props.defaultValue, keepActive: false, children: props.children, selectDate: props.children.filter(item => item.isChecked), defaultPlaceholder: props&&props.placeholder || this.translation.pleaseSelect } this.CommonMount = new CommonMount({ containerId: 'DropdownList_ul', // 容器ID follow: true, // 是否滚动跟随,默认true fixed: true// 定位:fixed,false时为absolute }); } componentWillReceiveProps(nextProps) { if (JSON.stringify(nextProps.children) != JSON.stringify(this.props.children)) { this.setState({ children: nextProps.children, selectDate: nextProps.children.filter(item => item.isChecked) }) } if (nextProps.defaultValue != this.state.defaultValue) { this.setState({defaultValue: nextProps.defaultValue}) } } componentDidUpdate() { const { textinput, formItem } = this.refs.inputbox.refs let renderNode = textinput ? textinput.parentNode : formItem && formItem.querySelector(".form-item__control_is-active") if(renderNode && this.state.keepActive && this.props.autoShowPanel) this.renderDOM(renderNode, this.state.selectDate) if (this.props.readonly || this.props.disabled) { this.CommonMount.unmountBox(); } } componentWillUnmount() { this.CommonMount.unmountBox(); } renderDOM(tar, selectDate) { if (!this.props.showPanel || !tar) return; let children = this.state.children; children.map((item,index) => { item.isChecked = false; selectDate.map((it, i) => { if (item.value == it.value) { item.isChecked = true; } }) }) let self = this; const dropdownDate = { "limitCount": this.props.limitCount, "multiple": this.props.multiple, "children": children.filter(item => !item.onlyShowInput), "dropdownWidth": this.props.dropDownWidth || tar.offsetWidth, "hasSearch": children.length > 10 && this.props.hasSearch!=false, "showAdvancedMode": this.props.showAdvancedMode, "onClick": function(event, val) { if ((typeof val=='object') && val.constructor==Array) { self.setState({selectDate: val, keepActive: false}) self.props.onClick && self.props.onClick(event, event.target, val) self.props.onChange && self.props.onChange(event, event.target, val) } else { self.setState({keepActive: false}) self.props.onClick && self.props.onClick(event, event.target, val) self.props.onChange && self.props.onChange(event, event.target, val) } self.CommonMount.unmountBox(); document.removeEventListener('mousedown', self.onClose); }, "onAdvancedModeClick": function (event) { self.setState({keepActive: false}) self.props.onAdvancedModeClick && self.props.onAdvancedModeClick(event) self.CommonMount.unmountBox(); document.removeEventListener('mousedown', self.onClose); }, emptyBgText: this.translation.emptyBgText, translation: this.translation } let dropHeight, documentHeight; documentHeight = document.body.scrollHeight == 0 ? document.documentElement.scrollHeight : document.body.scrollHeight; let dropcount = this.props.children.length>10?10:this.props.children.length; dropHeight = this.props.children.length>10?(this.props.multiple ? 374 : 270):(this.props.multiple ? dropcount*26+66 : dropcount*26+10); while(documentHeight < dropHeight) { dropHeight = dropHeight - 26; } let maxHeight = this.props.multiple ? (this.props.children.length > 10 ? dropHeight - 118 : dropHeight - 66) : dropHeight; maxHeight = maxHeight< 120 ? 120 : maxHeight; maxHeight = maxHeight>260 ?260:maxHeight; dropHeight = this.props.children.length ? dropHeight : 200 var hasSearch = this.props.children.length > 10 && this.props.hasSearch != false; if(!this.props.multiple) dropHeight = dropHeight + (hasSearch ? this.props.staticSearchHeight || 40 : 0) var isIE = !!window.ActiveXObject || "ActiveXObject" in window; const showAutoUl = <DropDown {...dropdownDate} hasSelectAll={this.props.hasSelectAll} /> let mountTarget = tar; for(let i = 0; i < tar.children.length; i++){ if(tar.children[i].tagName.toLowerCase() === 'input'){ mountTarget = tar.children[i]; break; } } this.CommonMount.renderDom( 'mount-box-dropdownlist', // wrap's classname & id showAutoUl, // content dom mountTarget, // 跟随目标 [ mountTarget, //挂载目标节点 { // 挂载元素宽高 {width: '', height: ''} width: this.props.dropDownWidth || tar.clientWidth,// 挂载宽度 height: dropHeight } ], false, //labeL和input框是否为竖向结构,会留出对应的label空间 0, //水平向左偏移量,为负数则向右 false, //弹层靠左靠右模式,默认为false 靠左模式 100 //window.onresize执行时间,默认100ms ,30 //输入框高度 ,(this.props.isSearchDrop && isIE ? false : undefined) //自定义zindex ); } clearToolTipDom = () => { let dom_1 = document.getElementById('DropdownList_ul'); if (dom_1) { let parNode = dom_1.parentNode; parNode.removeChild(dom_1); } } onClose = event => { try { findDOMNode(this); } catch(e) { this.CommonMount.unmountBox(); this.setState({keepActive: false}) document.removeEventListener('mousedown', this.onClose); this.props.onClose && this.props.onClose("close"); return; } // let selfDom = findDOMNode(this); let area = document.getElementById("DropdownList_ul"); if (area && !area.contains(event.target)) { if (event.target.className.indexOf('sys-icon-close')>-1|| event.target.className.indexOf('u-icon')>-1 || event.target.tagName === 'BODY') return; this.CommonMount.unmountBox(); this.setState({keepActive: false}) document.removeEventListener('mousedown', this.onClose); this.props.onClose && this.props.onClose("close"); } if (event.target.className == "btn btn_default btn_sm") { this.setState({keepActive: false}) } } handlerClick = (event, dom) => { setTimeout(() => { this.renderDOM(dom, this.state.selectDate) }, 0); this.setState({keepActive: true}) this.props.onFocus && this.props.onFocus(event) window.activeTarget = event; document.removeEventListener('mousedown', this.onClose); document.addEventListener('mousedown', this.onClose); } itemClose = (event, index, item) => { let selectDate = this.state.selectDate; selectDate = selectDate.filter(it => item.value != it.value) this.setState({selectDate: selectDate}) window.activeTarget = null; this.props.onClick && this.props.onClick(event, item, selectDate) this.props.onChange && this.props.onChange(event, item, selectDate) if (this.state.keepActive) { this.renderDOM(event.target.parentNode.parentNode, selectDate) } } render() { if (this.tar&&document.getElementById('mount-box-dropdownlist')) { let _bottom = this.tar.getBoundingClientRect().bottom; let _width = this.props.dropDownWidth || this.tar.offsetWidth; document.getElementById('mount-box-dropdownlist').style.top = _bottom + 'px'; document.getElementById('mount-box-dropdownlist').style.width = _width + 'px'; } let self = this; const {title,PromptMsg, errorStatus, errorMsg, helpMsg, multiple, disabled, readonly, required, hasClosebtn, lablePos, lableTxt, hasInput, showInput, isShowTips, sideTip} = this.props; let oriData = this.state.selectDate; oriData.map((item, index) => { item["value"] = item.value, item["name"] = item.text, item["isActive"] = item.isActive, item["tipText"] = item.tipText, item["isChecked"] = item.isChecked }) const inputDate = { "status": "" //展示态为show,编辑态为其他 ,"multiple": multiple //单选还是多选 ,'inputBoxReadonly': true ,titleDate: { "title": title //标题 ,"required": required //必选 ,"helpMsg": helpMsg //帮助信息,当为空时没有帮助信息 ,"lablePos": lablePos //label位置,true时在左边,false在上边 ,"lableTxt": lableTxt //label中文字对齐方式,true左对齐,false右对齐 } ,commonDate: { "defaultValue": this.state.defaultValue //默认文字 ,"placeholder": this.state.defaultPlaceholder //input中placeholder ,"keepActive": this.state.keepActive //保持蓝线一直存在 ,"PromptMsg": PromptMsg //提示信息,为空时不显示 ,"errorStatus": errorStatus //报错 ,"errorMsg": errorMsg //报错信息,为空时不显示 ,"disabled": disabled //input的disable状态,没有下划线 ,"readonly": readonly //input的readonly状态 ,"isShowTips": isShowTips //是否显示tooltip,若不传默认显示 ,"sideTip": sideTip //toolTip是否左右显示 } ,showDate: { "isLink": false //展示态是否是链接 ,"linkValue": "" //展示态链接地址 ,"selfJump": true //链接跳转方式 } ,singleDate: { "closeBtn": hasClosebtn==undefined||hasClosebtn?true:false //是否使用close按钮 ,"arrowdownBtn": true //是否使用下拉图标 ,"keepValue": true //用于带下拉,可以focue以及蓝线等,只是不可以输入值,通过defaultvalue改变 ,handlerClick: function(event, status, value) { if (readonly || disabled) return; // if (event.target.tagName == 'INPUT') { // self.handlerClick(event, event.target.parentNode) // } else { let target; if (event.className=='u-input') { target = event if(event.style.maxWidth.indexOf('calc')>=0) { target = event.parentNode; } } else if(event.target.className == 'u-input') { target = event.target.parentNode } else { target = event.target } self.handlerClick(event, target); // } } ,dropClick: function(event, value, dom) { self.handlerClick(event, dom.parentNode); } ,handlerChange: function(event, status, value) { self.props.onChange&&self.props.onChange(event, status, value) } } ,multiDate: { "hasInput": hasInput ,"showInput": showInput ,"selectDate": oriData//数据 ,handlerClick: function(event, dom) { self.handlerClick(event, dom) } ,itemClose: function(event, item, index, selectDate) { self.itemClose(event, index, item) } ,dropClick: function(event, status, dom) { self.handlerClick(event, dom); } } } return( <InputBox {...inputDate} ref="inputbox" /> ) } } module.exports = DropDownList;