import React,{Component} from 'react'; import style from './index.less'; import config from "@config/index"; import {filterArr,isIE} from '@utils/tools.js'; import Notify from '../Notify/index.js'; import $ from 'jquery'; /***** * author:zn@2018-12-10 * 自由文本输入组件 * 接收参数: * value:默认显示文字 * handleChange:输入变化时触发函数,接收以下参数: * * boxMark:病例项标识 * * i:标签index * * text:标签内文字 * * ****/ class EditableSpan extends Component{ constructor(props){ super(props); this.state={ timer:null, clearTimer:null, oldText:props.value, labelVal:'', //存放标签原有的值--主诉字数限制用 preVal:'', index:null, searchPre:'' }; this.$span = React.createRef(); this.handleFocus = this.handleFocus.bind(this); this.onChange = this.onChange.bind(this); this.handleBlur = this.handleBlur.bind(this); this.handleKeydown = this.handleKeydown.bind(this); this.handleKeyup = this.handleKeyup.bind(this); this.moveEnd = this.moveEnd.bind(this); } handleFocus(e){ e.stopPropagation(); const {setFocusIndex,i,boxMark}= this.props; let text = e.target.innerText; setFocusIndex&&setFocusIndex({i,boxMark,dom:this.$span}); this.setState({ labelVal:text, index:i, searchPre:text }); } onChange(e){ e.stopPropagation(); const {handleChange,boxMark,i,handleSearch,value,mainSaveText,mainIds} = this.props; const {labelVal,searchPre} = this.state; const text1 =e.target.innerText; let mainText = filterArr(mainSaveText);//主诉字数 if(+boxMark==1){ if(mainText.length >= config.limited){ if(text1.length > labelVal.length){ e.target.innerText = labelVal; Notify.info(config.limitText); return }else if(text1.length == labelVal.length){ this.setState({ labelVal:text1 }); }else{ handleChange&&handleChange({text1,boxMark,i}); } return } } this.setState({ labelVal:text1 }); const that = this; handleChange&&handleChange({text1,boxMark,i}); //延迟搜索 clearTimeout(this.state.timer); const timer = setTimeout(function(){ let newText = e.target.innerText; let temp = '',isEnd=false; let search=''; clearTimeout(that.state.timer); temp = newText.replace(searchPre,''); isEnd = !(newText.indexOf(searchPre)>0); search = temp.replace(/[(^\s*)|(\s*$)|(^\,*)|(\,*$)]/g,''); //console.log(labelVal,'旧:',searchPre,'新:',newText,'搜索:',search); handleSearch&&handleSearch({text:search,isEnd,boxMark,mainIds}); //搜索后保持现在的值,继续输入时要用于对比 that.setState({ searchPre:newText }); },config.delayTime); this.setState({ timer }); } handleBlur(e){//为了阻止冒泡事件 const {boxMark,handleClear,handleChange,i} = this.props; e.stopPropagation(); // 延时清空搜索结果,不延时会影响选中 clearTimeout(this.state.clearTimer); const clearTimer = setTimeout(function(){ handleClear && handleClear({boxMark}) },config.delayTime); this.setState({ clearTimer }); } moveEnd(obj) { if(window.getSelection){//ie11 10 9 ff safari obj.focus(); //解决ff不获取焦点无法定位问题 var range = window.getSelection();//创建range range.selectAllChildren(obj);//range 选择obj下所有子内容 range.collapseToEnd();//光标移至最后 } else if (document.selection) {//ie10 9 8 7 6 5 var range = document.selection.createRange();//创建选择对象 range.moveToElementText(obj);//range定位到obj range.collapse(false);//光标移至最后 range.select(); } } handleKeydown(e){ const ev = e||window.event; const target = ev.target||ev.srcElement; let innerVal = target.innerText; /*if(this.props.full){ return false; }*/ //禁止回车事件 if(ev.keyCode==13){return false;} //backspace事件 if(ev.keyCode==8){ //用于对比backspace前后的值 this.setState({ preVal:innerVal }) } } handleKeyup(e){ const {boxMark,handleKeydown,i,value,removeId} = this.props; const {preVal,index} = this.state; const ev = e||window.event; const target = ev.target||ev.srcElement; let innerVal = target.innerText; if(ev.keyCode==8){ // 主诉现病史去重:删除最后一个字的时候移除该数据(将name、id和value替换成空)并移除id // 前面是标签,内容为空时再删一次才移除标签;前面是文本,则直接移除; let preObj = $(this.$span.current).prev(); if(preVal.trim().length==1){ removeId && removeId({boxMark,i:index,text:""}); if(preObj[0].nodeName !=="DIV"){ this.moveEnd(preObj[0]); } } if(innerVal !==preVal){return false} let data = innerVal.trim(); //判断是否为空、中英文:, 。、;,且不是第一位 let pattern = new RegExp(/^\,?$|^\,?$|^\.?$|^\。?$|^\、?$|^\;?$|^\;?$|^\:?$|^\:?$\s/); if(index!==0 && pattern.test(data)){ // let preObj = $(this.$span.current).prev(); let obj = preObj[0].nodeName=="DIV"?preObj.prev():preObj; handleKeydown&&handleKeydown({boxMark,i:index,text:data}); this.moveEnd(obj[0]); this.setState({ index: null }) } } } /*shouldComponentUpdate(next){ if(JSON.stringify(next) == JSON.stringify(this.props)){ return false; } return true; }*/ componentWillReceiveProps(next){ const isRead = this.props.isRead; if(next.isRead != isRead){ this.$span.current.innerText = next.value||''; } } componentDidMount(){ const {value} = this.props; if(value){ this.$span.current.innerText = value||''; } if(isIE()){ $(this.$span.current).onIe8Input(function(e){ this.onChange(e) },this); } } render() { return ; } } export default EditableSpan;