@beisen/dropdown-list
Version:
DropDownList
298 lines (286 loc) • 11.2 kB
JavaScript
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;