index.jsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import React,{Component} from 'react';
  2. import style from './index.less';
  3. import config from "@config/index";
  4. import {filterArr,isIE} from '@utils/tools.js';
  5. import Notify from '../Notify/index.js';
  6. import $ from 'jquery';
  7. /*****
  8. * author:zn@2018-12-10
  9. * 自由文本输入组件
  10. * 接收参数:
  11. * value:默认显示文字
  12. * handleChange:输入变化时触发函数,接收以下参数:
  13. * * boxMark:病例项标识
  14. * * i:标签index
  15. * * text:标签内文字
  16. *
  17. * ****/
  18. class EditableSpan extends Component{
  19. constructor(props){
  20. super(props);
  21. this.state={
  22. timer:null,
  23. clearTimer:null,
  24. oldText:props.value,
  25. labelVal:'', //存放标签原有的值--主诉字数限制用
  26. preVal:'',
  27. index:null,
  28. searchPre:''
  29. };
  30. this.$span = React.createRef();
  31. this.handleFocus = this.handleFocus.bind(this);
  32. this.onChange = this.onChange.bind(this);
  33. this.handleBlur = this.handleBlur.bind(this);
  34. this.handleKeydown = this.handleKeydown.bind(this);
  35. this.handleKeyup = this.handleKeyup.bind(this);
  36. }
  37. handleFocus(e){
  38. e.stopPropagation();
  39. const {setFocusIndex,i,boxMark}= this.props;
  40. let text = e.target.innerText;
  41. setFocusIndex&&setFocusIndex({i,boxMark,dom:this.$span});
  42. this.setState({
  43. labelVal:text,
  44. index:i,
  45. searchPre:text
  46. });
  47. }
  48. onChange(e){
  49. e.stopPropagation();
  50. const {handleChange,boxMark,i,handleSearch,value,mainSaveText,mainIds} = this.props;
  51. const {labelVal,searchPre} = this.state;
  52. const text1 =e.target.innerText;
  53. let mainText = filterArr(mainSaveText);//主诉字数
  54. if(+boxMark==1){
  55. if(mainText.length >= config.limited){
  56. if(text1.length > labelVal.length){
  57. e.target.innerText = labelVal;
  58. Notify.info(config.limitText);
  59. return
  60. }else if(text1.length == labelVal.length){
  61. this.setState({
  62. labelVal:text1
  63. });
  64. }else{
  65. handleChange&&handleChange({text1,boxMark,i});
  66. }
  67. return
  68. }
  69. }
  70. this.setState({
  71. labelVal:text1
  72. });
  73. const that = this;
  74. handleChange&&handleChange({text1,boxMark,i});
  75. //延迟搜索
  76. clearTimeout(this.state.timer);
  77. const timer = setTimeout(function(){
  78. let newText = e.target.innerText;
  79. let temp = '';
  80. let search='';
  81. clearTimeout(that.state.timer);
  82. temp = newText.replace(searchPre,'');
  83. search = temp.replace(/[(^\s*)|(\s*$)|(^\,*)|(\,*$)]/g,'');
  84. //console.log(labelVal,'旧:',searchPre,'新:',newText,'搜索:',search);
  85. handleSearch&&handleSearch({text:search,boxMark,mainIds});
  86. //搜索后保持现在的值,继续输入时要用于对比
  87. that.setState({
  88. searchPre:newText
  89. });
  90. },config.delayTime);
  91. this.setState({
  92. timer
  93. });
  94. }
  95. handleBlur(e){//为了阻止冒泡事件
  96. const {boxMark,handleClear,handleChange,i} = this.props;
  97. e.stopPropagation();
  98. // 延时清空搜索结果,不延时会影响选中
  99. clearTimeout(this.state.clearTimer);
  100. const clearTimer = setTimeout(function(){
  101. handleClear && handleClear({boxMark})
  102. },config.delayTime);
  103. this.setState({
  104. clearTimer
  105. });
  106. }
  107. handleKeydown(e){
  108. const ev = e||window.event;
  109. const target = ev.target||ev.srcElement;
  110. let innerVal = target.innerText;
  111. //禁止回车事件
  112. if(ev.keyCode==13){return false;}
  113. //backspace事件
  114. if(ev.keyCode==8){
  115. //用于对比backspace前后的值
  116. this.setState({
  117. preVal:innerVal
  118. })
  119. }
  120. }
  121. handleKeyup(e){
  122. const {boxMark,handleKeydown,i,value} = this.props;
  123. const {preVal,index} = this.state;
  124. const ev = e||window.event;
  125. const target = ev.target||ev.srcElement;
  126. let innerVal = target.innerText;
  127. if(ev.keyCode==8){
  128. if(innerVal !==preVal){return}
  129. let data = innerVal.trim();
  130. //判断是否为空、中英文:, 。、;,且不是第一位
  131. let pattern = new RegExp(/^\,?$|^\,?$|^\.?$|^\。?$|^\、?$|^\;?$|^\;?$|^\:?$|^\:?$\s/);
  132. // if(i!==0 &&data==""||data==","||data==","||data==":"||data==":"||data=="."||data=="。"||data=="、"||data==";"||data==";"){
  133. if(index!==0 && pattern.test(data)){
  134. handleKeydown&&handleKeydown({boxMark,i:index});
  135. this.setState({
  136. // index:index-1 //连续往前删除,体验不佳
  137. index: null
  138. })
  139. }
  140. }
  141. }
  142. /*shouldComponentUpdate(next){
  143. if(JSON.stringify(next) == JSON.stringify(this.props)){
  144. return false;
  145. }
  146. return true;
  147. }*/
  148. componentWillReceiveProps(next){
  149. const isRead = this.props.isRead;
  150. if(next.isRead != isRead){
  151. this.$span.current.innerText = next.value||'';
  152. }
  153. }
  154. componentDidMount(){
  155. const {value} = this.props;
  156. if(value){
  157. this.$span.current.innerText = value||'';
  158. }
  159. if(isIE()){
  160. $(this.$span.current).onIe8Input(function(e){
  161. this.onChange(e)
  162. },this);
  163. }
  164. }
  165. render() {
  166. return <span className={style['editable-span']}
  167. contentEditable='true'
  168. ref={this.$span}
  169. onInput={this.onChange}
  170. onFocus={this.handleFocus}
  171. onBlur={this.handleBlur}
  172. onkeydown={this.handleKeydown}
  173. onkeyup={this.handleKeyup}></span>;
  174. }
  175. }
  176. export default EditableSpan;