import React,{Component} from 'react'; import className from 'classnames'; import {NumberPan,Notify} from '@commonComp'; import style from './index.less'; import {setFontColorSize,handleMouseUp} from '@utils/tools' /*** * author:zn@2018-11-19 * 接收参数: * value: 默认选中的值 * placeholder:灰显文字 * handleSelect: 选中事件 * show: 是否显示下拉 * allClick:是否前后缀也可唤出数字键盘 * * ***/ class NumberDrop extends Component{ constructor(props){ super(props); this.state={ /*editable:false, //标签是否可输入*/ value:props.value||'', timer:null, sltTimer:null, blurTimer:null, hasSelect:false, //是否点过下拉键盘 placeholder:props.placeholder }; this.$span = React.createRef(); this.numInpBlur = this.numInpBlur.bind(this); this.handleSpanInp = this.handleSpanInp.bind(this); this.handleNumClick = this.handleNumClick.bind(this); this.handleNumFocus = this.handleNumFocus.bind(this); this.handleKeyDowm = this.handleKeyDowm.bind(this); this.beyondArea = this.beyondArea.bind(this); this.emitBMIData = this.emitBMIData.bind(this); } select(text){ //选中键盘上数字事件 //placeholder修改后,第一次点击键盘触发blur后onClick不触发,原因未知,改为onMouseup可触发 let timer = null; clearTimeout(this.state.sltTimer); clearTimeout(this.state.blurTimer); const {handleSelect,ikey,suffix,prefix,mainSaveText,min,max,formulaCode} = this.props; const needCompare=min!=undefined&&max!=undefined; if(!text){ this.setState({ placeholder:this.props.placeholder }); }else{ if(needCompare){ const that = this; const isFine = this.validSymbols(text,min,max); //有~或/时是否合理 const hasSymbol = /[\/|\~]/g.test(text); //是否有~或/ const singleFine = !isNaN(+text)&&parseFloat(min)<=parseFloat(text)&&parseFloat(text)<=parseFloat(max); //无~或/时是否合理 timer = setTimeout(function(){ clearTimeout(that.state.sltTimer); if(text!=''&&(!hasSymbol&&!singleFine)||(hasSymbol&&!isFine)){ that.beyondArea(); return; } },1500); } this.setState({ hasSelect:true, sltTimer:timer }); } handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText,formulaCode}); //BMI相关数据上传 this.emitBMIData(text); } emitBMIData(text){ //手动修改BMI相关值时数据上传 const {setBMIParam,formulaCode,setBMI} = this.props; if(formulaCode==="BMI_RES"){ setBMI&&setBMI(text); } if(text!==0&&(formulaCode==="BMI_SG"||formulaCode==="BMI_TZ")){ const map={ BMI_SG:'tall', BMI_TZ:'weight' }; setTimeout(function(){ setBMIParam&&setBMIParam(map[formulaCode],text); }); } } beyondArea(){ const {handleSelect,ikey,suffix,prefix,mainSaveText,formulaCode} = this.props; Notify.info("输入数值不符合规范,请重新输入!"); handleSelect&&handleSelect({ikey,text:'',suffix,prefix,mainSaveText,formulaCode}); this.emitBMIData(''); this.setState({ placeholder:this.props.placeholder, hasSelect:false }); } handleNumFocus(e){ /*const {placeholder} = this.state; const val = e.target.innerText.trim(); //console.log(33,e.target.innerText,placeholder,e.target.innerText.trim() == placeholder) if(val!=''&&val == placeholder){ this.setState({ placeholder:'' }); }*/ e.stopPropagation(); } handleKeyDowm(e){ if(e.keyCode==13){ const {reFocus,num,handleHide} = this.props; reFocus&&reFocus(num); handleHide && handleHide(); } } handleNumClick(e){ //数字框不可编辑的状态时点击事件,点击将数字框变为可输入且下拉不再显示直到失焦后再次聚集 e.stopPropagation(); const {show,handleShow,ikey,id,patId,handleHide} = this.props; if(show) { handleHide && handleHide(); return; }else{ this.$span.current.focus(); this.setState({ hasSelect:false, placeholder:'' //火狐26placeholder点击不隐藏bug修改 }); handleShow&&handleShow({ikey,id:patId||id}); } } validSymbols(txt,min,max){ //输入只有一个~或/时判断两边是否为合理数字,有多个为不合理 const index1 = txt.indexOf('~'); const index2 = txt.indexOf('/'); const needCompare = min!=undefined&&max!=undefined; let arr1=[],arr2=[]; if(index1!=-1&&index1==txt.lastIndexOf('~')&&index1!=txt.length-1){ //有且只有一个~,且不在最后 arr1 = txt.split('~'); //~的范围在合理范围内为合理值 if(!isNaN(+arr1[0])&&!isNaN(+arr1[1])&&((!needCompare)||(needCompare&&parseFloat(min)<=parseFloat(arr1[0])&&parseFloat(arr1[0])<=parseFloat(max)&&parseFloat(min)<=parseFloat(arr1[1])&&parseFloat(arr1[1])<=parseFloat(max)))){ return true } return false; } if(index2!=-1&&index2==txt.lastIndexOf('/')&&index2!=txt.length-1){ //有且只有一个~,且不在最后 arr2 = txt.split('/'); // /两边的数字分别在合理范围内为合理值 if(!isNaN(+arr2[0])&&!isNaN(+arr2[1])&&((!needCompare)||(needCompare&&parseFloat(min)<=parseFloat(arr2[0])&&parseFloat(arr2[0])<=parseFloat(max)&&parseFloat(min)<=parseFloat(arr2[1])&&parseFloat(arr2[1])<=parseFloat(max)))){ return true } return false; } return false; } numInpBlur(e){ //数字框失焦,保存值到store中 e.stopPropagation(); const {handleSelect,ikey,suffix,prefix,mainSaveText,min,max,show,formulaCode} = this.props; /*if(show){ //修改清空后第一次点击键盘不触发click事件bug--失焦placehoder消失,弃用 return; }*/ //输入超出合理范围或输入不是数字提示且清空 const needCompare=min!=undefined&&max!=undefined; const txt = e.target.innerHTML.replace(/ $|^ /,'');//e.target.innerText.trim(); const isFine = this.validSymbols(txt,min,max); //有~或/时是否合理 const hasSymbol = /[\/|\~]/g.test(txt); //是否有~或/ const singleFine = (!isNaN(+txt)&&!needCompare)||(!isNaN(+txt)&&needCompare&&parseFloat(min)<=parseFloat(txt)&&parseFloat(txt)<=parseFloat(max)); //无~或/时是否合理 if(txt!=''&&(!hasSymbol&&!singleFine)||(hasSymbol&&!isFine)){ this.beyondArea(); return; } //输入为空时显示placeholder const timer = setTimeout(()=>{ if(!e.target.innerHTML.replace(/ $|^ /,'')){ this.setState({ placeholder:this.props.placeholder }); } },200); this.setState({ blurTimer:timer }); const val = e.target.innerHTML.replace(/ $|^ /,'');//e.target.innerText.trim(); const {placeholder} = this.state; let text = val===placeholder?'':val; //e.target.innerText = ''; //避免出现重复输入值 handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText,formulaCode}); this.emitBMIData(text); } handleSpanInp(e){ //数字框输入事件 e.stopPropagation(); const txt = e.target.innerHTML.replace(/ $|^ /,''); this.setState({ value:txt }); const {handleHide} = this.props; handleHide&&handleHide(); } getClasses(nospecial){ //整个标签是否有值的状态 const {hideTag,placeholder,isImports,isExtBlue,isSelectAll,mouseSelect} = this.props; const val = this.state.value; const isSelected = val&&val!=placeholder?style['selected']:style['container']; const orgBorder = isImports&&!(val&&val!=placeholder)?style['orange-border']:''; const ext = isExtBlue?style['ext']:''; const noTag = hideTag?style['no-tag']:''; const selectedArea = mouseSelect?style['selected-area']:''; return className(isSelected,noTag,orgBorder,ext,setFontColorSize(val||isSelectAll?'2,6':isExtBlue?2:1),selectedArea); } getSpanClass(nospecial){ //将被替换的文字选中状态显示 const {isSelectAll,isExtBlue,show,mouseSelect} = this.props; const val = this.state.value; const selectedArea = mouseSelect?style['selected-area']:''; const cls = this.props.show?style['blued']:style['nol']; // return cls+' '+setFontColorSize(nospecial?'':2); return className(show?style['blued']:(style['nol'],setFontColorSize(val?'2,6':isSelectAll?'2,6':isExtBlue?2:1)),selectedArea) } stopBubble(e){ e.stopPropagation(); } handleMouseDown(){ const {i,setSelectArea,boxMark}= this.props; setSelectArea({i,boxMark,dir:'start'}); } componentDidMount(){ //设置最小宽度避免输入后宽度跳动 const spanWidth = window.getComputedStyle(this.$span.current).width; this.$span.current.style.minWidth=spanWidth; //保存输入框dom以便聚焦 const that = this; setTimeout(function(){ //多个其他史/现病史bug修改 const {saveDoms} = that.props; saveDoms&&saveDoms(that.$span); }) } componentWillReceiveProps(nextProps){ //BMI存值 const {formulaCode,bmi,suffix,prefix,ikey,handleSelect,mainSaveText,wrBmi} = this.props; if(formulaCode==="BMI_RES"&&nextProps.bmi!==bmi){ handleSelect&&handleSelect({ikey,text:nextProps.bmi,suffix,prefix,mainSaveText,formulaCode}); } //手动修改BMI时身高体重清空 if(wrBmi!==nextProps.wrBmi&&(formulaCode==="BMI_SG"||formulaCode==="BMI_TZ")){ handleSelect&&handleSelect({ikey,text:'',suffix,prefix,mainSaveText,formulaCode}); } if((nextProps.placeholder == this.props.placeholder)&&(nextProps.value == this.props.value)){ return } this.setState({ placeholder:nextProps.placeholder, value:nextProps.value }); } render(){ const {prefix,suffix,show,value,handleHide,allClick,bmi,formulaCode,nospecial,isSelectAll,isExtBlue,select_start,i,boxMark} = this.props; const val = formulaCode==="BMI_RES"?(+bmi===Infinity||isNaN(bmi)?'':bmi):value; const {placeholder,hasSelect} = this.state; return
handleMouseUp({select_start,i,boxMark})} onMouseDown={this.handleMouseDown.bind(this)}> {prefix}  {val||placeholder} {suffix}
} } export default NumberDrop;