index.jsx 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. import React,{Component} from 'react';
  2. import {handleEnter,getPageCoordinate,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. editable:false,
  22. timer:null,
  23. boxLeft:0,
  24. boxTop:0,
  25. tmpScroll:0,
  26. tmpTop:0,
  27. texts:props.vals||{0:props.value||props.placeholder},
  28. over:false
  29. };
  30. this.$cont = React.createRef();
  31. this.isIE = navigator.appName=="Microsoft Internet Explorer" && navigator.appVersion.split(";")[1].replace(/[ ]/g,"")=="MSIE8.0";
  32. this.handleSelect = this.handleSelect.bind(this);
  33. this.handleShow = this.handleShow.bind(this);
  34. this.handledbClick = this.handledbClick.bind(this);
  35. this.handleEditLabel = this.handleEditLabel.bind(this);
  36. this.parseInputDom = this.parseInputDom.bind(this);
  37. this.handleInnerInp = this.handleInnerInp.bind(this);
  38. }
  39. getClass(){
  40. const {value,hideTag,placeholder,show,isImports} = this.props;
  41. const blueBorder = this.state.editable?style['blue-border']:'';
  42. const orgBorder = isImports&&!value?style['orange-border']:'';
  43. if(show){
  44. $(this.$cont.current).addClass(style['borderd']);
  45. }else{
  46. $(this.$cont.current).removeClass(style['borderd']);
  47. }
  48. if(hideTag){
  49. return style['no-tag'];
  50. }
  51. if(value){
  52. return blueBorder?classNames(style['selected-tag'],blueBorder):style['selected-tag'];
  53. }
  54. return classNames(style['tag'],orgBorder);
  55. }
  56. handleSelect(item){
  57. const {handleSelect,ikey,value,placeholder,mainSaveText} = this.props;
  58. let vals = {}, inx = 0;
  59. if(!item){
  60. handleSelect&&handleSelect({ikey}); //清空
  61. this.setState({
  62. texts:{0:placeholder}
  63. });
  64. return ;
  65. }
  66. const arr = item.name.split(config.radioOptionPer);
  67. arr.map((it,i)=>{
  68. inx = (i+1)*2-2;
  69. vals[inx] = it;
  70. if(i!=arr.length-1){
  71. vals[+inx+1]={value:'',index:+inx+1}
  72. };
  73. });
  74. this.setState({
  75. texts:vals
  76. });
  77. handleSelect&&handleSelect({ikey,id:item.id,values:vals,mainSaveText,value});
  78. }
  79. handleShow(e){
  80. //e.stopPropagation();
  81. const {handleShow,ikey,id,patId} = this.props;
  82. const that = this;
  83. const timer = setTimeout(function(){
  84. if (that.state.editable) {//如果处于编辑状态点击不显示下拉框
  85. return
  86. }else {
  87. handleShow && handleShow({ikey,id:patId||id});
  88. }
  89. },300);
  90. this.setState({
  91. timer,
  92. boxLeft:getPageCoordinate(e).boxLeft,
  93. boxTop:getPageCoordinate(e).boxTop,
  94. tmpScroll: $("#addScrollEvent")[0].scrollTop,
  95. tmpTop:getPageCoordinate(e).boxTop
  96. });
  97. windowEventHandler('scroll',()=>{ //弹窗跟随滚动条滚动或者关闭弹窗
  98. let scrollYs = $("#addScrollEvent")[0].scrollTop;
  99. this.setState({
  100. boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
  101. })
  102. },$("#addScrollEvent")[0])
  103. }
  104. /*componentDidMount(){ //默认值选中
  105. const {data,ikey,handleSelect} = this.props;
  106. const selected = data.find((it)=>{
  107. return it.selected === undefined&&+it.defaultSelect===1;
  108. });
  109. if(selected){
  110. // const text = selected.labelPrefix+selected.name+selected.labelSuffix;
  111. const text = selected.name;
  112. handleSelect&&handleSelect({ikey,id:selected.id,text});
  113. }
  114. }*/
  115. handleEditLabel(e){
  116. e.stopPropagation();
  117. if(!this.state.editable){ //ie8点开下拉未选值存值bug修改
  118. return;
  119. }
  120. const {ikey,boxMark,handleLabelEdit} = this.props;
  121. this.setState({
  122. editable:false
  123. });
  124. // 更改标签的value值
  125. const ev = e || window.event;
  126. let changeVal = ev.target.innerText || ev.target.innerHTML;
  127. if(!this.isIE){
  128. ev.target.innerText?(ev.target.innerText = ''):(ev.target.innerHTML = '');
  129. }
  130. handleLabelEdit && handleLabelEdit({ikey,changeVal,type:boxMark});
  131. }
  132. handledbClick(e){
  133. const {value,id,handleDbclick,patId} = this.props;
  134. clearTimeout(this.state.timer);//取消延时的单击事件
  135. //e.preventDefault();
  136. if(value&&value.trim()) {//有选中值的标签才能双击编辑
  137. this.setState({
  138. editable: true
  139. });
  140. };
  141. //失焦关闭编辑状态
  142. setTimeout(()=>{
  143. e.target.focus();
  144. })
  145. handleDbclick&&handleDbclick({id:patId||id});
  146. }
  147. handleInnerInp(i,val){
  148. const {ikey,boxMark,handleSaveInp,mainSaveText} = this.props;
  149. let vals = this.state.texts;
  150. // 主诉字数限制
  151. if(boxMark==1){
  152. let preText = vals[i].value;
  153. let mainText = filterDataArr(mainSaveText);
  154. let lengths = 0;
  155. if(preText){
  156. lengths = mainText.length + (val.length - preText.length);
  157. }else{
  158. lengths = mainText.length + val.length;
  159. }
  160. //console.log("val:",val,"preVal:",preText,"mainText:",mainText,"lengths:",lengths,this.state.texts)
  161. if(lengths >= config.limited){
  162. Notify.info(config.limitText);
  163. this.setState({
  164. over:true
  165. });
  166. return
  167. }
  168. }
  169. vals[i].value=val;
  170. this.setState({
  171. texts:vals,
  172. over:false
  173. });
  174. handleSaveInp({values:vals,ikey,boxMark,mainSaveText});
  175. }
  176. parseInputDom(){
  177. const {value,placeholder} = this.props;
  178. const {texts,over} = this.state;
  179. let temp='',list=[];
  180. for(let i in texts){
  181. temp = texts[i];
  182. if(typeof temp=='object'){
  183. list.push(<InputComp handleInp={this.handleInnerInp} editable={true} index={i} value={temp.value} over={over}></InputComp>);
  184. }else{
  185. list.push(<span>&nbsp;{temp}</span>);
  186. }
  187. }
  188. /*if(value&&value.indexOf(config.radioOptionPer)!=-1){
  189. let arr = [],inpIndex='';
  190. let list = value.split(config.radioOptionPer);
  191. list.map((it,i)=>{
  192. arr.push(<InputComp value={it}></InputComp>);
  193. inpIndex = (i+1)*2-1;
  194. if(i!=list.length-1){
  195. arr.push(<InputComp handleInp={this.handleInnerInp} editable={true} index={inpIndex}></InputComp>);
  196. }
  197. });
  198. return arr;
  199. }*/
  200. return list;
  201. }
  202. render(){
  203. const {data,show,vals,placeholder} = this.props;
  204. const {boxLeft,boxTop} = this.state;
  205. return <div className={style['container']} ref = {this.$cont}>
  206. <div className={this.getClass()}
  207. onBlur={this.handleEditLabel}
  208. contentEditable={this.state.editable}
  209. onDoubleClick={this.handledbClick}
  210. onClick={(e)=>this.handleShow(e,true)}
  211. onkeydown={handleEnter}>
  212. {vals?this.parseInputDom():<span>{placeholder}</span>}
  213. </div>
  214. <DropList onSelect={this.handleSelect} data={data} left={boxLeft} top={boxTop} show={show}/>
  215. </div>
  216. }
  217. }
  218. //单选项中的输入框
  219. class InputComp extends Component{
  220. constructor(props){
  221. super(props);
  222. this.$inp = React.createRef();
  223. this.handleBlur = this.handleBlur.bind(this);
  224. }
  225. handleBlur(e){
  226. e.stopPropagation();
  227. const text = e.target.innerText;
  228. const {handleInp,index,value} = this.props;
  229. e.target.innerText = '';
  230. handleInp(index,text);
  231. }
  232. componentWillReceiveProps(next){
  233. if(next.over&&!this.props.over){
  234. const inp = this.$inp.current;
  235. const value = this.props.value;
  236. setTimeout(function(){
  237. inp.innerText = value;
  238. })
  239. }
  240. }
  241. render(){
  242. const {editable,value} = this.props;
  243. return editable?<span contentEditable={true}
  244. ref={this.$inp}
  245. className={style['inner-inp']}
  246. onClick={(e)=>{e.stopPropagation()}}
  247. onFocus={(e)=>{e.stopPropagation()}}
  248. onBlur={this.handleBlur}>&nbsp;{value}</span>:<span>&nbsp;{value}</span>
  249. }
  250. }
  251. export default RadioInpDrop;