index.jsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import React,{Component} from 'react';
  2. import className from 'classnames';
  3. import {NumberUnitPan} from '@commonComp';
  4. import style from './index.less';
  5. import config from '@config/index.js';
  6. import {filterArr,handleEnter,isIE} from '@utils/tools.js';
  7. import {Notify} from '@commonComp';
  8. import $ from 'jquery';
  9. /***
  10. * 带单位数字组件
  11. * 接收参数:
  12. * value: 默认选中的值
  13. * placeholder:灰显文字
  14. * handleSelect: 选中事件
  15. * show: 是否显示下拉
  16. *
  17. * ***/
  18. class NumberUnitDrop extends Component{
  19. constructor(props){
  20. super(props);
  21. this.state={
  22. editable:false, //标签是否可输入
  23. numEditable:true, //数字框是否可输入
  24. timer:null,
  25. hasSelect:false, //是否点过下拉键盘
  26. isClosed:false,
  27. value:props.value,
  28. placeholderFlag:false,
  29. labelVal:''
  30. };
  31. this.$span = React.createRef();
  32. this.$cont = React.createRef();
  33. this.select = this.select.bind(this);
  34. this.numInpBlur = this.numInpBlur.bind(this);
  35. this.handleSpanInp = this.handleSpanInp.bind(this);
  36. this.handleNumClick = this.handleNumClick.bind(this);
  37. this.changeToEdit = this.changeToEdit.bind(this);
  38. }
  39. select(text){ //选中键盘上数字事件
  40. const {handleSelect,ikey,suffix,prefix,mainSaveText} = this.props;
  41. this.setState({
  42. hasSelect:true
  43. });
  44. if(!text){
  45. this.setState({
  46. value:''
  47. });
  48. }
  49. handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText});
  50. }
  51. handleNumClick(e){
  52. e.stopPropagation();
  53. const {show,handleShow,ikey,id,patId,handleHide,value} = this.props;
  54. const {hasSelect} = this.state;
  55. const that = this;
  56. //双击时不显示下拉
  57. clearTimeout(this.state.timer);
  58. const timer = setTimeout(function(){
  59. const {hasSelect,editable,isClosed} = that.state;
  60. if(editable||isClosed){
  61. return;
  62. }
  63. handleShow&&handleShow({ikey,id:patId||id});
  64. },300);
  65. this.setState({
  66. timer
  67. });
  68. handleHide&&handleHide();
  69. }
  70. //数字框失焦,保存值到store中
  71. numInpBlur(e){
  72. e.stopPropagation();
  73. const {handleSelect,ikey,suffix,prefix,mainSaveText,handleLabelChange,boxMark} = this.props;
  74. const {editable} = this.state;
  75. if(editable){
  76. const text = e.target.innerText;
  77. // this.$span.current.innerText=''; //修改生成文字变成输入的2倍bug
  78. // handleSelect&&handleSelect({ikey,text,suffix,prefix,mainSaveText});
  79. handleLabelChange&&handleLabelChange({ikey,changeVal:text,suffix,prefix,mainSaveText,type:boxMark});
  80. }
  81. this.setState({
  82. isClosed:false,
  83. numEditable:true,
  84. hasSelect:false,
  85. editable:false
  86. });
  87. }
  88. handleSpanInp(e){ //数字框输入事件
  89. e.stopPropagation();
  90. // 主诉字数达到上限时不允许输入
  91. const {mainSaveText,ikey,type,handleSelect,suffix,prefix,boxMark} = this.props;
  92. const {labelVal,editable} = this.state;
  93. let mainText = filterArr(mainSaveText);//主诉字数
  94. if(editable){//避免IE中点击标签也会触发
  95. let val = e.target.innerText;
  96. if(+boxMark==1){
  97. if(mainText.length >= config.limited){
  98. if(val.length > labelVal.length){
  99. e.target.innerText = labelVal;
  100. Notify.info(config.limitText);
  101. return
  102. }else if(val.length == labelVal.length){
  103. this.setState({
  104. labelVal:val
  105. });
  106. }else{
  107. handleSelect&&handleSelect({ikey,text:val,suffix,prefix,mainSaveText});
  108. }
  109. }
  110. }
  111. }
  112. }
  113. getClasses(){ //整个标签是否有值的状态
  114. const {value,hideTag,show} = this.props;
  115. const inpValue = this.state.value;
  116. const isSelected = value||inpValue?style['selected']:style['container'];
  117. const noTag = hideTag?style['no-tag']:'';
  118. if(show){
  119. $(this.$cont.current).addClass(style['borderd']);
  120. }else{
  121. $(this.$cont.current).removeClass(style['borderd']);
  122. }
  123. return className(isSelected,noTag);
  124. }
  125. changeToEdit(e){ //整个标签双击编辑状态
  126. e.stopPropagation();
  127. const {value,id,handleDbclick,patId} = this.props;
  128. const text = e.target.innerText;
  129. // clearTimeout(this.state.timer);//取消延时的单击事件
  130. if(value&&value.trim()) {//有选中值的标签才能双击编辑
  131. this.setState({
  132. editable: true,
  133. labelVal:text
  134. });
  135. e.target.focus();
  136. //双击埋点记录
  137. handleDbclick && handleDbclick({id:patId||id});
  138. }
  139. }
  140. componentDidMount(){
  141. if(isIE()){
  142. $(this.$span.current).onIe8Input(function(e){
  143. this.handleSpanInp(e)
  144. },this);
  145. }
  146. }
  147. render(){
  148. const {placeholder,prefix,suffix,show,value,handleHide} = this.props;
  149. const {numEditable,editable,hasSelect,placeholderFlag} = this.state;
  150. return <div className={this.getClasses()} ref={this.$cont}>
  151. <span>{prefix}</span>
  152. <span onClick={this.handleNumClick}
  153. contentEditable={editable}
  154. ref = {this.$span}
  155. onBlur={this.numInpBlur}
  156. onInput={this.handleSpanInp}
  157. onDoubleClick={this.changeToEdit}
  158. onkeydown={handleEnter}
  159. style={{cursor:editable?'text':'pointer'}}>{value||placeholder}</span>
  160. <span>{suffix}</span>
  161. <NumberUnitPan handleSelect={(text)=>this.select(text)}
  162. onClose={handleHide}
  163. show={show} toClear={!hasSelect} value={value}/>
  164. </div>
  165. }
  166. }
  167. export default NumberUnitDrop;