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} from '@utils/tools.js';
import {Notify} from '@commonComp';
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:null,
boxTop:null
};
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
})
// 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 = filterArr(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} = this.props;
const params = Object.assign({},this.state,{ikey,type,tagType,order,mainSaveText,copyType});
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(){
if(this.props.show){
$(this.$div.current).addClass(style['borderd']);
}else{
$(this.$div.current).removeClass(style['borderd']);
}
if(this.props.value){
return style['selected-tag'];
}
return style['tag'];
}
getLabels(){
const {data} = 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