import React,{Component} from 'react'; import className from 'classnames'; import {NumberPan,Notify} from '@commonComp'; import style from './index.less'; import $ from "jquery"; import {handleEnter,getPageCoordinate} from '@utils/tools.js'; /*** * author:zn@2018-11-19 * 接收参数: * value: 默认选中的值 * placeholder:灰显文字 * handleSelect: 选中事件 * show: 是否显示下拉 * allClick:是否前后缀也可唤出数字键盘 * * ***/ class NumberDrop extends Component{ constructor(props){ super(props); this.state={ editable:false, //标签是否可输入 timer:null, sltTimer:null, hasSelect:false, //是否点过下拉键盘 boxLeft:0, boxTop:0, tmpTop:0, tmpScroll:0, placeholder:props.placeholder }; this.$span = React.createRef(); this.$pre = React.createRef(); this.$suf = React.createRef(); this.$cont = React.createRef(); this.select = this.select.bind(this); 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.handleBlur = this.handleBlur.bind(this); this.changeToEdit = this.changeToEdit.bind(this); this.handleKeyDowm = this.handleKeyDowm.bind(this); this.beyondArea = this.beyondArea.bind(this); } select(text){ //选中键盘上数字事件 let timer = null; clearTimeout(this.state.sltTimer); const {handleSelect,ikey,suffix,prefix,mainSaveText,min,max} = this.props; const needCompare=min!=undefined&&max!=undefined; if(!text){ this.setState({ placeholder:this.props.placeholder }); }else{ //console.log(text,isNaN(+text),max<+text) if(needCompare){ if(!isNaN(+text)&&max<+text){ //数值过大 this.beyondArea(); return; } const that = this; timer = setTimeout(function(){ clearTimeout(that.state.sltTimer); if(!that.props.show&&!isNaN(+text)&&min>+text){ that.beyondArea(); return; } },1500); } this.setState({ hasSelect:true, sltTimer:timer }); } handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText}); } beyondArea(){ const {handleSelect,ikey,suffix,prefix,mainSaveText} = this.props; Notify.info("数值在正常值范围内,请重新输入"); handleSelect&&handleSelect({ikey,text:'',suffix,prefix,mainSaveText}); 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(); } handleNumClick(e){ //数字框不可编辑的状态时点击事件,点击将数字框变为可输入且下拉不再显示直到失焦后再次聚集 const {show,handleShow,ikey,id,patId,handleHide,value} = this.props; this.$span.current.focus(); if(show) { handleHide && handleHide(); return; }else{ const {editable} = this.state; if(editable){ return; } const that = this; //双击时不显示下拉 clearTimeout(that.state.timer); const timer = setTimeout(function(){ //只有弹窗关闭则点击数字键盘会清空当前数据 that.setState({ hasSelect:false }); handleShow&&handleShow({ikey,id:patId||id}); },300); this.setState({ timer, boxLeft:getPageCoordinate(e).boxLeft, boxTop:getPageCoordinate(e).boxTop, tmpScroll: $("#addScrollEvent")[0].scrollTop, tmpTop:getPageCoordinate(e).boxTop }); $("#addScrollEvent").scroll(()=>{ let scrollYs = $("#addScrollEvent")[0].scrollTop; this.setState({ boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll }) }) } e.stopPropagation(); } numInpBlur(e){ //数字框失焦,保存值到store中 e.stopPropagation(); const {handleSelect,ikey,suffix,prefix,mainSaveText,min,max,show} = this.props; if(show){ //修改清空后第一次点击键盘不触发click事件bug return; } const txt = e.target.innerText.replace(/^\s*/,''); if(max!=undefined&&!isNaN(+txt)&&(min>+txt||max<+txt)){ this.beyondArea(); return; } //输入为空时显示placeholder if(!e.target.innerText.trim()){ this.setState({ placeholder:this.props.placeholder }); } /*this.setState({ hasSelect:false });*/ const val = e.target.innerText.replace(/^\s*/,''); const {placeholder} = this.state; let text = val===placeholder?'':val.replace(/[\u4e00-\u9fa5]/g,''); e.target.innerText = ''; //避免出现重复输入值 handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText}); } handleSpanInp(e){ //数字框输入事件 e.stopPropagation(); const {handleHide} = this.props; /*this.setState({ //再键盘点击数字要清空 hasSelect:false });*/ handleHide&&handleHide(); } handleKeyDowm(e){ handleEnter(); //只能输入数字 const key = e.key; const ctrlOn = e.ctrlKey; const isCopyPaste = ctrlOn&&(key=='v'||key=='c'); if((!/[0-9|.|~|\/]/.test(key)&&key.length==1&&!isCopyPaste)){ e.preventDefault(); return false; } } getClasses(){ //整个标签是否有值的状态 const {hideTag,placeholder,value} = this.props; const $span = this.$span.current; const val = value;//$span&&$span.innerText.trim()||value; const blueBorder = this.state.editable?style['blue-border']:''; const isSelected = val&&val!=placeholder?style['selected']:style['container']; const noTag = hideTag?style['no-tag']:''; return className(isSelected,noTag,blueBorder); } changeToEdit(e){ //整个标签双击编辑状态 const {value,id,handleDbclick,patId,handleHide,show} = this.props; clearTimeout(this.state.timer);//取消延时的单击事件 e.preventDefault(); if(show){ handleHide&&handleHide(); } if(value&&value.trim()) {//有选中值的标签才能双击编辑 this.setState({ editable: true }); setTimeout(()=>{ this.$cont.current.focus(); }) //双击埋点记录 handleDbclick && handleDbclick({id:patId||id}); } } handleBlur(e){ //双击编辑blur const {handleLabelChange,ikey,boxMark,value} = this.props; //if(!this.state.editable) return; this.setState({ editable: false }); let totalVal = e.target.innerText; let changeVal = this.$span.current.innerText.replace(/^\s*/,'');//数字框值-修改后;去掉前空格避免多空格叠加 let prefix = this.$pre.current.innerText.replace(/^\s*/,''); //前缀值-修改后 let suffix = this.$suf.current.innerText.replace(/^\s*/,''); //后缀值-修改后 //console.log('数字框:'+changeVal,";全部:"+totalVal,";前缀:"+prefix+";后缀:"+suffix); handleLabelChange && handleLabelChange({ikey,changeVal,type:boxMark,totalVal,prefix,suffix}); } getSpanClass(){ //将被替换的文字选中状态显示 //const {hasSelect} = this.state; const cls = this.props.show?style['blued']:''; return cls; } componentDidMount(){ //设置最小宽度避免输入后宽度跳动 const spanWidth = window.getComputedStyle(this.$span.current).width; this.$span.current.style.minWidth=spanWidth; } render(){ const {prefix,suffix,show,value,handleHide,allClick} = this.props; const {numEditable,placeholder,editable,hasSelect,boxTop,boxLeft} = this.state; return