index.jsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import React,{Component} from 'react';
  2. import {handleEnter,windowEventHandler,filterDataArr,getLabelIndex,setFontColorSize} from '@utils/tools.js';
  3. import {DropList,Notify} from '@commonComp';
  4. import config from '@config/index';
  5. import style from "./index.less";
  6. import classNames from 'classnames';
  7. import $ from "jquery";
  8. /****
  9. * 单选下拉,选项带输入
  10. * author:zn@2019-3.18
  11. * 接收参数:
  12. * placeholder:灰显文字
  13. * data:下拉内容数据
  14. * handleSelect:选中事件
  15. *
  16. * ***/
  17. class RadioInpDrop extends Component{
  18. constructor(props){
  19. super(props);
  20. this.state={
  21. texts:props.vals||{0:props.value||props.placeholder},
  22. };
  23. this.$cont = React.createRef();
  24. this.isIE = navigator.appName=="Microsoft Internet Explorer" && navigator.appVersion.split(";")[1].replace(/[ ]/g,"")=="MSIE8.0";
  25. this.handleSelect = this.handleSelect.bind(this);
  26. this.handleShow = this.handleShow.bind(this);
  27. this.parseInputDom = this.parseInputDom.bind(this);
  28. this.handleInnerBlur = this.handleInnerBlur.bind(this);
  29. }
  30. getClass(){
  31. const {value,hideTag,show,isImports,isExtBlue,mouseSelect} = this.props;
  32. const orgBorder = isImports&&!value?style['orange-border']:''; //查体,是否橙色框高亮
  33. const ext = isExtBlue?style['ext']:''; //查体,是否是体征
  34. const selectedArea = mouseSelect?style['selected-area']:'';
  35. if(show){
  36. $(this.$cont.current).addClass(style['borderd']);
  37. }else{
  38. $(this.$cont.current).removeClass(style['borderd']);
  39. }
  40. if(value){
  41. if(hideTag){
  42. return classNames(style['no-tag'],ext,setFontColorSize(),selectedArea);
  43. }
  44. return classNames(style['selected-tag'],setFontColorSize(),selectedArea);
  45. }else{
  46. if(hideTag){
  47. return classNames(style['no-tag'],ext,setFontColorSize(2),selectedArea);
  48. }
  49. return classNames(style['tag'],orgBorder,ext,setFontColorSize(2,6),selectedArea);
  50. }
  51. }
  52. handleSelect(item){
  53. const {handleSelect,ikey,value,placeholder,mainSaveText} = this.props;
  54. let vals = {}, inx = 0;
  55. if(!item){
  56. handleSelect&&handleSelect({ikey}); //清空
  57. this.setState({
  58. texts:{0:placeholder}
  59. });
  60. return ;
  61. }
  62. const arr = item.name.split(config.radioOptionPer);
  63. arr.map((it,i)=>{
  64. inx = (i+1)*2-2;
  65. vals[inx] = it;
  66. if(i!=arr.length-1){
  67. vals[+inx+1]={value:'',index:+inx+1}
  68. };
  69. });
  70. this.setState({
  71. texts:vals
  72. });
  73. handleSelect&&handleSelect({ikey,id:item.id,values:vals,mainSaveText,value});
  74. }
  75. handleShow(e){
  76. e.stopPropagation();
  77. const {handleShow,ikey,id,patId} = this.props;
  78. document.activeElement.blur()//chrome41有效,但是失去焦点的span仍能编辑
  79. handleShow && handleShow({ikey,id:patId||id});
  80. windowEventHandler('scroll',()=>{ //弹窗跟随滚动条滚动或者关闭弹窗
  81. let scrollYs = $("#addScrollEvent")[0].scrollTop;
  82. this.setState({
  83. boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
  84. })
  85. },$("#addScrollEvent")[0])
  86. }
  87. handleInnerBlur(i,val){
  88. const {ikey,boxMark,handleSaveInp,mainSaveText} = this.props;
  89. let vals = this.state.texts;
  90. vals[i].value=val;
  91. this.setState({
  92. texts:vals,
  93. });
  94. handleSaveInp({values:vals,ikey,boxMark,mainSaveText});
  95. }
  96. handleMouseUp(){
  97. const {select_start,i,setSelectArea,boxMark}= this.props;
  98. if(select_start!==undefined){
  99. setSelectArea({i,boxMark,dir:'end'});
  100. }
  101. }
  102. handleMouseDown(){
  103. const {i,setSelectArea,boxMark}= this.props;
  104. setSelectArea({i,boxMark,dir:'start'});
  105. }
  106. parseInputDom(){
  107. const {mainSaveText,ikey,boxMark} = this.props;
  108. const {texts} = this.state;
  109. const inx = ikey.split("-")[1];
  110. let temp='',list=[];
  111. for(let i in texts){
  112. temp = texts[i];
  113. if(typeof temp=='object'){
  114. list.push(<InputComp handleBlur={this.handleInnerBlur}
  115. mainSaveText={mainSaveText}
  116. index={i}
  117. inx = {inx}
  118. texts={texts}
  119. boxMark={boxMark}
  120. value={temp.value}
  121. ></InputComp>);
  122. }else{
  123. list.push(<span className="inheritStyle">&nbsp;{temp}</span>);
  124. }
  125. }
  126. return list;
  127. }
  128. render(){
  129. const {data,show,vals,placeholder} = this.props;
  130. return <div className={style['container']} ref = {this.$cont}>
  131. <div className={this.getClass()}
  132. onClick={(e)=>this.handleShow(e)}
  133. onMouseUp={this.handleMouseUp.bind(this)}
  134. onMouseDown={this.handleMouseDown.bind(this)}
  135. onKeyDown={handleEnter}>
  136. {vals?this.parseInputDom():<span className='inheritStyle'>{placeholder}</span>}
  137. </div>
  138. <DropList onSelect={this.handleSelect} data={data} show={show}/>
  139. </div>
  140. }
  141. }
  142. //单选项中的输入框
  143. class InputComp extends Component{
  144. constructor(props){
  145. super(props);
  146. this.$inp = React.createRef();
  147. this.handleBlur = this.handleBlur.bind(this);
  148. this.handleInp = this.handleInp.bind(this);
  149. }
  150. handleBlur(e){
  151. e.stopPropagation();
  152. if(this.over){
  153. return;
  154. }
  155. // FF26 只有innerHTML
  156. const text = e.target.innerText || e.target.innerHTML;
  157. const {handleBlur,index} = this.props;
  158. e.target.innerHTML = '';
  159. // FF26 会把&nbsp; 也获取到
  160. handleBlur(index,text.replace('&nbsp;',''));
  161. }
  162. getTextVal(obj=[],index){
  163. let str = '';
  164. Object.keys(obj).map((it)=>{
  165. if(typeof obj[it]==='string'){
  166. str += obj[it];
  167. }else{
  168. if(it!==index){ //当前输入框文字不记录,避免重复计算
  169. str += obj[it].value;
  170. }
  171. }
  172. });
  173. return str;
  174. }
  175. handleInp(e){
  176. const val = e.target.innerText||e.target.innerHTML;
  177. const {mainSaveText,value,index,texts,inx,boxMark} = this.props;
  178. if(boxMark==='1'){
  179. const textVal = this.getTextVal(texts,index); //已存的单选含自由输入生成的文字
  180. const tempArr = [...mainSaveText];
  181. tempArr.splice(inx,1);
  182. const otherVal = tempArr.join(""); //主诉其他的已填文字
  183. //console.log(textVal,otherVal,val)
  184. //超出主诉限制提示并不可继续输入
  185. if((textVal+otherVal+val).length>config.limited){
  186. e.target.innerHTML=value||'';
  187. this.over=true;
  188. //e.target.blur();
  189. Notify.info(config.limitText);
  190. return;
  191. }
  192. this.over=false;
  193. }
  194. this.over=false;
  195. }
  196. componentWillReceiveProps(next){
  197. //超过限制时,再点开下拉被删除的输入文字又出现bug修改
  198. const inp = this.$inp.current;
  199. const value = next.value;
  200. inp.innerHTML = '';
  201. setTimeout(function(){
  202. inp.innerHTML = value;
  203. });
  204. }
  205. render(){
  206. const {value} = this.props;
  207. return <span contentEditable={true}
  208. ref={this.$inp}
  209. className={`${style['inner-inp']}`}
  210. onClick={(e)=>{e.stopPropagation()}}
  211. onFocus={(e)=>{e.stopPropagation()}}
  212. onInput={this.handleInp}
  213. onBlur={this.handleBlur}>&nbsp;</span>
  214. }
  215. }
  216. export default RadioInpDrop;