index.jsx 6.3 KB

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