index.jsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. import React,{Component} from 'react';
  2. import className from 'classnames';
  3. import {NumberPan} from '@commonComp';
  4. import style from './index.less';
  5. import $ from "jquery";
  6. import {handleEnter,getPageCoordinate} from '@utils/tools.js';
  7. /***
  8. * author:zn@2018-11-19
  9. * 接收参数:
  10. * value: 默认选中的值
  11. * placeholder:灰显文字
  12. * handleSelect: 选中事件
  13. * show: 是否显示下拉
  14. *
  15. * ***/
  16. class NumberDrop extends Component{
  17. constructor(props){
  18. super(props);
  19. this.state={
  20. editable:false, //标签是否可输入
  21. timer:null,
  22. hasSelect:false, //是否点过下拉键盘
  23. boxLeft:0,
  24. boxTop:0,
  25. tmpTop:0,
  26. tmpScroll:0
  27. };
  28. this.$span = React.createRef();
  29. this.$pre = React.createRef();
  30. this.$suf = React.createRef();
  31. this.$cont = React.createRef();
  32. this.select = this.select.bind(this);
  33. this.numInpBlur = this.numInpBlur.bind(this);
  34. this.handleSpanInp = this.handleSpanInp.bind(this);
  35. this.handleNumClick = this.handleNumClick.bind(this);
  36. this.handleNumFocus = this.handleNumFocus.bind(this);
  37. this.handleBlur = this.handleBlur.bind(this);
  38. this.changeToEdit = this.changeToEdit.bind(this);
  39. }
  40. select(text){ //选中键盘上数字事件
  41. const {handleSelect,ikey,suffix,prefix,mainSaveText} = this.props;
  42. this.setState({
  43. hasSelect:true
  44. });
  45. handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText});
  46. }
  47. handleNumFocus(e){ //数字框可编辑状态下聚集事件,处理是否显示下拉等
  48. e.stopPropagation();
  49. }
  50. handleNumClick(e){ //数字框不可编辑的状态时点击事件,点击将数字框变为可输入且下拉不再显示直到失焦后再次聚集
  51. const {show,handleShow,ikey,id,patId,handleHide,value} = this.props;
  52. if(show) {
  53. handleHide && handleHide();
  54. return;
  55. }else{
  56. const {editable} = this.state;
  57. if(editable){
  58. return;
  59. }
  60. const that = this;
  61. //双击时不显示下拉
  62. clearTimeout(that.state.timer);
  63. const timer = setTimeout(function(){
  64. handleShow&&handleShow({ikey,id:patId||id});
  65. },300);
  66. this.setState({
  67. timer,
  68. boxLeft:getPageCoordinate(e).boxLeft,
  69. boxTop:getPageCoordinate(e).boxTop,
  70. tmpScroll: $("#addScrollEvent")[0].scrollTop,
  71. tmpTop:getPageCoordinate(e).boxTop
  72. });
  73. $("#addScrollEvent").scroll(()=>{
  74. let scrollYs = $("#addScrollEvent")[0].scrollTop;
  75. this.setState({
  76. boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
  77. })
  78. })
  79. }
  80. e.stopPropagation();
  81. }
  82. numInpBlur(e){ //数字框失焦,保存值到store中
  83. e.stopPropagation();
  84. this.setState({
  85. hasSelect:false
  86. });
  87. const val = e.target.innerText.replace(/^\s*/,'');
  88. const {handleSelect,ikey,suffix,prefix,mainSaveText,placeholder} = this.props;
  89. const text = val===placeholder?'':val;
  90. e.target.innerText = ''; //避免出现重复输入值
  91. handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText});
  92. }
  93. handleSpanInp(e){ //数字框输入事件
  94. e.stopPropagation();
  95. const {handleHide} = this.props;
  96. handleHide&&handleHide();
  97. }
  98. getClasses(){ //整个标签是否有值的状态
  99. const {value,hideTag,placeholder} = this.props;
  100. const blueBorder = this.state.editable?style['blue-border']:'';
  101. const isSelected = value&&value!=placeholder?style['selected']:style['container'];
  102. const noTag = hideTag?style['no-tag']:'';
  103. return className(isSelected,noTag,blueBorder);
  104. }
  105. changeToEdit(e){ //整个标签双击编辑状态
  106. const {value,id,handleDbclick,patId,handleHide,show} = this.props;
  107. clearTimeout(this.state.timer);//取消延时的单击事件
  108. e.preventDefault();
  109. if(show){
  110. handleHide&&handleHide();
  111. }
  112. if(value&&value.trim()) {//有选中值的标签才能双击编辑
  113. this.setState({
  114. editable: true
  115. });
  116. setTimeout(()=>{
  117. this.$cont.current.focus();
  118. })
  119. //双击埋点记录
  120. handleDbclick && handleDbclick({id:patId||id});
  121. }
  122. }
  123. handleBlur(e){ //双击编辑blur
  124. const {handleLabelChange,ikey,boxMark,value} = this.props;
  125. //if(!this.state.editable) return;
  126. this.setState({
  127. editable: false
  128. });
  129. let totalVal = e.target.innerText;
  130. let changeVal = this.$span.current.innerText.replace(/^\s*/,'');//数字框值-修改后;去掉前空格避免多空格叠加
  131. let prefix = this.$pre.current.innerText.replace(/^\s*/,''); //前缀值-修改后
  132. let suffix = this.$suf.current.innerText.replace(/^\s*/,''); //后缀值-修改后
  133. //console.log('数字框:'+changeVal,";全部:"+totalVal,";前缀:"+prefix+";后缀:"+suffix);
  134. handleLabelChange && handleLabelChange({ikey,changeVal,type:boxMark,totalVal,prefix,suffix});
  135. }
  136. getSpanClass(){ //将被替换的文字选中状态显示
  137. //const {hasSelect} = this.state;
  138. const cls = this.props.show?style['blued']:'';
  139. return cls;
  140. }
  141. render(){
  142. const {placeholder,prefix,suffix,show,value,handleHide} = this.props;
  143. const {numEditable,editable,hasSelect,boxTop,boxLeft} = this.state;
  144. return <div className={this.getClasses()}
  145. ref={this.$cont}
  146. onDoubleClick={this.changeToEdit}
  147. contentEditable={editable}
  148. onBlur={this.handleBlur}
  149. onkeydown={handleEnter}>
  150. <span ref = {this.$pre}>&nbsp;{prefix}</span>
  151. <span onFocus={this.handleNumFocus}
  152. onClick={this.handleNumClick}
  153. contentEditable={true}
  154. style={{minWidth:'10px',display:'inline-block'}}
  155. ref = {this.$span}
  156. onBlur={this.numInpBlur}
  157. onInput={this.handleSpanInp}
  158. className={this.getSpanClass()}
  159. onkeydown={handleEnter}>&nbsp;{value||placeholder}</span>
  160. <span ref = {this.$suf}>&nbsp;{suffix}</span>
  161. <NumberPan handleSelect={(text)=>this.select(text)}
  162. onClose={handleHide}
  163. show={show}
  164. toClear={!hasSelect}
  165. left={boxLeft}
  166. top={boxTop}/>
  167. </div>
  168. }
  169. }
  170. export default NumberDrop;