import React,{Component} from 'react'; import classNames from 'classnames'; import config from '@config/index.js'; import style from './index.less'; import {deepClone,filterArr,handleEnter,isIE,getPageCoordinate,windowEventHandler,filterDataArr} from '@utils/tools.js'; import {Notify} from '@commonComp'; import ReactDom from "react-dom"; import {getIds} from '@common/js/func.js'; import $ from 'jquery'; /**** * 标签组合下拉,选中的项目展开 * author:zn@2018-11-21 * 接收参数: * keepSelf:展开标签后是否保留原标签 * data:下拉内容 * placeholder:灰显文字 * * ***/ class SpreadDrop extends Component{ constructor(props){ super(props); const {nones,noneOn,noneIds,withOn,exists,nowOn,withs,exclusion,excluName} = deepClone(props.selecteds||[]); this.state = { nones:nones||'', //无,字符串拼接 exists:exists||[], //主症状id excluName:excluName||'', withs:withs||[], //伴随 id noneIds:noneIds||[], noneOn:noneOn||false, //无是否选中 withOn:withOn||false, //伴是否选中 nowOn:nowOn||'', //最近选中“无”还是“伴” exclusion:exclusion||'', //选中互斥项id timer:null, //延时,区分单击双击 ban:{}, //放'伴'字段 editable:false, //双击编辑 labelVal:'', //存放标签原有的值--主诉字数限制用 boxLeft:0, boxTop:0, tmpScroll:0, tmpTop:0, }; this.$div = React.createRef(); this.handleSelect = this.handleSelect.bind(this); this.clearState = this.clearState.bind(this); this.handleClear = this.handleClear.bind(this); this.handleShow = this.handleShow.bind(this); this.handleConfirm = this.handleConfirm.bind(this); this.changeToEdit = this.changeToEdit.bind(this); this.handleBlur = this.handleBlur.bind(this); this.onChange = this.onChange.bind(this); /*是否点击确定按钮标记,处理点击其他等同于确定操作bug, 如不区分确定按钮提交和点击其他提交,确定按钮提交后会多更新一次状态导致数据重复*/ this.btnClickFlag = false; } handleShow(e){//单击 e&&e.stopPropagation(); // let boxLeft = e.pageX -175 + 'px'; // let offsetTop = e.target.offsetTop; // const ht = e.target.offsetHeight; //如杂音选中文字有多行时,写死会遮挡 // let boxTop = offsetTop + ht +2 + 'px'; // this.setState({ // boxLeft:boxLeft, // boxTop:boxTop // }) this.setState({ boxLeft:getPageCoordinate(e).boxLeft, boxTop:getPageCoordinate(e).boxTop, tmpScroll: $("#addScrollEvent")[0].scrollTop, tmpTop:getPageCoordinate(e).boxTop }); windowEventHandler('scroll',()=>{ //弹窗跟随滚动条滚动或者关闭弹窗 let scrollYs = $("#addScrollEvent")[0].scrollTop; this.setState({ boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll }) },$("#addScrollEvent")[0]) // window.event? window.event.cancelBubble = true : e.stopPropagation(); this.setStateInit(); //恢复初始选中状态 const {ikey,handleShow,placeholder,flag,id,value,tagType,type} = this.props; const that = this; this.btnClickFlag = false; clearTimeout(this.state.timer); this.state.timer = setTimeout(function(){ if (that.state.editable) {//如果处于编辑状态点击不显示下拉框 return }else{ handleShow&&handleShow({ikey,placeholder,flag,id,value,tagType,type}); } },300) } changeToEdit(e){//双击 const {value,id,placeholder,handleDbclick,handleHide} = this.props; let text = e.target.innerText; handleHide&&handleHide(); //展开情况下双击收起 // clearTimeout(this.state.timer);//取消延时的单击事件 e.stopPropagation(); // e.preventDefault(); if(value&&value.trim()){//有选中值的标签才能双击编辑 this.setState({ labelVal:text, editable:true }); e.target.focus(); handleDbclick && handleDbclick({value,id,placeholder}); } } onChange(e){ const {mainSaveText,ikey,type,handleLabelChange} = this.props; const {labelVal,editable} = this.state; let mainText = filterDataArr(mainSaveText);//主诉字数 if(editable){//避免IE中点击标签也会触发 let val = e.target.innerText; if(+type==1){// 主诉字数达到上限时不允许输入 if(mainText.length >= config.limited){ if(val.length > labelVal.length){ e.target.innerText = labelVal; Notify.info(config.limitText); return }else if(val.length == labelVal.length){ this.setState({ labelVal:val }); }else{ handleLabelChange && handleLabelChange({ikey,changeVal:val,type}); } } } } } handleBlur(e){ e.stopPropagation(); const {ikey,type,handleLabelChange} = this.props; const {editable} = this.state; const ev = e || window.event; if(editable){ // 更改标签的value值 let changeVal = ev.target.innerText; if(!isIE()){ e.target.innerText = ''; //避免出现重复输入值 } handleLabelChange && handleLabelChange({ikey,changeVal,type}); } this.setState({ editable:false }); } setStateInit(){ const {nones,noneOn,noneIds,withOn,exists,nowOn,withs,exclusion,excluName} = deepClone(this.props.selecteds||[]); this.setState({ nones:nones||'', exists:exists||[], excluName:excluName||'', withs:withs||[], noneIds:noneIds||[], noneOn:noneOn||false, withOn:withOn||false, nowOn:nowOn||'', exclusion:exclusion||'', ban:{}, }); } clearState(){ this.setState({ nones:'', exists:[], //existsName:{}, //withsName:{}, withs:[], noneIds:[], noneOn:false, withOn:false, nowOn:'', exclusion:'', excluName:'', ban:{} }); this.btnClickFlag = false; } handleClear(e){ e.stopPropagation(); this.clearState(); } handleConfirm(e){ e.stopPropagation(); const {handleConfirm,ikey,type,tagType,order,mainSaveText,copyType,value} = this.props; const params = Object.assign({},this.state,{ikey,type,tagType,order,mainSaveText,copyType,value}); handleConfirm&&handleConfirm(params); this.btnClickFlag = true; //点确定后隐藏弹窗 this.props.handleHide(); } handleSelect(item,isExclu,joint,listIndex,selected){ let {withOn,withs,noneOn,exclusion,exists,nowOn,nones,noneIds,ban} = this.state; /*if(this.props.selecteds) console.log(exists,this.props.selecteds.exists,exists===this.props.selecteds.exists)*/ const id = item.id; const linkStr = joint||''; const name = item.name+linkStr; if(isExclu){ //操作“互斥项” if([...noneIds,...exists,...withs].length>0){ //已选非互斥项,互斥项不可操作 return; } let temp = ''; if(exclusion==''){ temp = id; }else if(exclusion!=''&&exclusion!==id){ temp = exclusion; } this.setState({ exclusion:temp, excluName:temp ===''?'':name }); return; } //操作单选项 if(selected){ const tIndex= exists.findIndex((it)=>it.id===selected.id); if(tIndex!=-1){ exists.splice(tIndex,1,{id,name,listIndex}); this.setState({ exists, }) } return; } if(exclusion!==''){ //互斥项被选中,其他不可操作 return; } if(+item.code===1){ //操作“伴”类型 this.setState({ withOn:!withOn, // withs:withOn?[]:[...withs,id], //取消“伴”选中,伴随症状全部取消选中 // withs:withOn?[]:[...withs,{id:item.id,name:name}], withs:withOn?[]:withs, ban:withOn?{}:{id:id,name:name}, //withsName:withOn?"":withsName+name, //取消“伴”选中,伴随症状全部取消选中 nowOn:withOn?(noneOn?'none':''):'with' }); return; } if(+item.code===2){ //操作“无”类型 this.setState({ noneOn:!noneOn, noneIds:noneOn?[]:[...noneIds,id], nones:noneOn?'':name, nowOn:noneOn?(withOn?'with':''):'none' }); return; } //操作普通项 let existsIds = exists.length>0? getIds(exists):[]; let withsIds = withs.length>0? getIds(withs):[]; if(existsIds.includes(id)){ let existsData = exists; exists.forEach((it,i)=>{ if(it.id==id){ existsData.splice(i,1); } }) exists = existsData; }else if(noneIds.includes(id)){ nones = nones.replace(name+'、',''); noneIds.splice(noneIds.indexOf(id),1); }else if(withsIds.includes(id)){ let withsData = withs; withs.forEach((it,i)=>{ if(it.id==id){ withsData.splice(i,1); } }) withs = withsData; }else{ //选中普通项 if(nowOn=='none'){ nones += name+'、'; noneIds.push(id); }else if(nowOn=='with'){ withs.push({id:id,name:name}); }else{ exists.push({id:id,name:name,listIndex}); } } this.setState({ nones, noneIds, exists, withs, ban //existsName, //withsName, }); } getClass(){ const blueBorder = this.state.editable?style['blue-border']:''; if(this.props.show){ $(this.$div.current).addClass(style['borderd']); }else{ $(this.$div.current).removeClass(style['borderd']); } if(this.props.value){ return classNames(style['selected-tag'],blueBorder); } return style['tag']; } componentDidMount(){ if(isIE()){ $(this.$div.current).onIe8Input(function(e){ this.onChange(e) },this); } } render(){ const {placeholder,value,show,data} = this.props; const {editable,boxLeft,boxTop} = this.state; return
e.stopPropagation()} onBlur={(e)=>e.stopPropagation()} onInput={(e)=>e.stopPropagation()}>
{value||placeholder}
} } class ListItems extends Component{ constructor(props){ super(props); } getLabels(){ const {data,handleSelect} = this.props; let detail = []; let isSpecialPos = false; //是否特殊位置(单行在上面,如无殊) let isExclu = false; //是否与其他互斥 let isRadio; //是否为单选列,默认多选列 const list = data&&data.map((it,i)=>{ isSpecialPos = (+it.formPosition === 1); isExclu = (+it.exclusionType===1); isRadio = (+it.tagType ===1&&+it.controlType === 1); if(+it.controlType===0){ detail = it.questionMapping; }else{ detail = it.questionDetailList; } return ; }); return list; } getStyle(){ const {left,top,show} = this.props; return { left:left?left+'px':'', top:top?top+'px':'', display:show?'block':'none' } } render (){ const {handleClear,handleConfirm} = this.props; const domNode = document.getElementById('root'); return ReactDom.createPortal(
{e.stopPropagation();}}> {this.getLabels()}
清空选项 确定
,domNode) } } class ListItem extends Component{ constructor(props){ super(props); } handleClick(e,item,i){ e.stopPropagation(); // window.event? window.event.cancelBubble = true : e.stopPropagation(); const {handleClick,isExclu,isRadio,data,exists,noneIds,withs,joint,listIndex} = this.props; const index=listIndex+''+i; //列单选处理 if(isRadio){ const selected = data.find((it)=>{ return exists.findIndex((i)=>i.id===it.id)!==-1||noneIds.includes(it.id)||withs.findIndex((i)=>i.id===it.id)!==-1; }); if(selected&&selected.id!=item.id){ //该列已有选中项,传回已选中的id,name取消选中 handleClick&&handleClick(item,isExclu,joint,index,{id:selected.id,name:selected.name}); }else{ handleClick&&handleClick(item,isExclu,joint,index); } return; } handleClick&&handleClick(item,isExclu,joint,index); } getClass(id){ //无之后显示黑色,之前显示蓝色 const {exclusion,nones,noneIds,exists,withs,isExclu,ban} = this.props; if(exclusion!=''){ if(+id===+exclusion){ return style['selected']; }else{ return style['exclusion']; } }else{ if(isExclu&&[...noneIds,...exists,...withs].length>0){ return style['exclusion']; } if(noneIds.includes(id)){ return style['none-selected']; } let existsIds = getIds(exists); let withsIds = getIds(withs); // if(existsIds.includes(id)||withsIds.includes(id)){ if(existsIds.includes(id)||withsIds.includes(id)||ban.id && ban.id==id){ return style['selected']; } return ''; } } render(){ const {datas,isSpecialPos} = this.props; const pos = isSpecialPos?style['independent']:''; return ; } } export default SpreadDrop;