index.jsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import React,{Component} from 'react';
  2. import {handleEnter,getPageCoordinate,windowEventHandler} from '@utils/tools.js';
  3. import {DropList} from '@commonComp';
  4. import config from '@config/index';
  5. import style from "./index.less";
  6. import $ from "jquery";
  7. /****
  8. * 单选下拉,选项带输入
  9. * author:zn@2019-3.18
  10. * 接收参数:
  11. * placeholder:灰显文字
  12. * data:下拉内容数据
  13. * handleSelect:选中事件
  14. * prefix:前缀
  15. * suffix:后缀
  16. *
  17. * ***/
  18. class RadioInpDrop extends Component{
  19. constructor(props){
  20. super(props);
  21. this.state={
  22. editable:false,
  23. timer:null,
  24. boxLeft:0,
  25. boxTop:0,
  26. tmpScroll:0,
  27. tmpTop:0,
  28. texts:props.vals||{0:props.value||props.placeholder}
  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} = this.props;
  41. const blueBorder = this.state.editable?style['blue-border']:'';
  42. if(show){
  43. $(this.$cont.current).addClass(style['borderd']);
  44. }else{
  45. $(this.$cont.current).removeClass(style['borderd']);
  46. }
  47. if(hideTag){
  48. return style['no-tag'];
  49. }
  50. if(value){
  51. return blueBorder?style['selected-tag']+' '+blueBorder:style['selected-tag'];
  52. }
  53. return style['tag'];
  54. }
  55. handleSelect(item){
  56. const {handleSelect,ikey,mainSaveText,value,placeholder} = this.props;
  57. let vals = {}, inx = 0;
  58. if(!item){
  59. handleSelect&&handleSelect({ikey}); //清空
  60. this.setState({
  61. texts:{0:placeholder}
  62. });
  63. return ;
  64. }
  65. const arr = item.name.split(config.radioOptionPer);
  66. arr.map((it,i)=>{
  67. inx = (i+1)*2-2;
  68. vals[inx] = it;
  69. if(i!=arr.length-1){
  70. vals[+inx+1]={value:'',index:+inx+1}
  71. };
  72. });
  73. this.setState({
  74. texts:vals
  75. });
  76. handleSelect&&handleSelect({ikey,id:item.id,values:vals,mainSaveText});
  77. }
  78. handleShow(e){
  79. //e.stopPropagation();
  80. const {handleShow,ikey,id,patId} = this.props;
  81. const that = this;
  82. const timer = setTimeout(function(){
  83. if (that.state.editable) {//如果处于编辑状态点击不显示下拉框
  84. return
  85. }else {
  86. handleShow && handleShow({ikey,id:patId||id});
  87. }
  88. },300);
  89. this.setState({
  90. timer,
  91. boxLeft:getPageCoordinate(e).boxLeft,
  92. boxTop:getPageCoordinate(e).boxTop,
  93. tmpScroll: $("#addScrollEvent")[0].scrollTop,
  94. tmpTop:getPageCoordinate(e).boxTop
  95. });
  96. windowEventHandler('scroll',()=>{ //弹窗跟随滚动条滚动或者关闭弹窗
  97. let scrollYs = $("#addScrollEvent")[0].scrollTop;
  98. this.setState({
  99. boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
  100. })
  101. },$("#addScrollEvent")[0])
  102. }
  103. /*componentDidMount(){ //默认值选中
  104. const {data,ikey,handleSelect} = this.props;
  105. const selected = data.find((it)=>{
  106. return it.selected === undefined&&+it.defaultSelect===1;
  107. });
  108. if(selected){
  109. // const text = selected.labelPrefix+selected.name+selected.labelSuffix;
  110. const text = selected.name;
  111. handleSelect&&handleSelect({ikey,id:selected.id,text});
  112. }
  113. }*/
  114. handleEditLabel(e){
  115. e.stopPropagation();
  116. if(!this.state.editable){ //ie8点开下拉未选值存值bug修改
  117. return;
  118. }
  119. const {ikey,boxMark,handleLabelEdit} = this.props;
  120. this.setState({
  121. editable:false
  122. });
  123. // 更改标签的value值
  124. const ev = e || window.event;
  125. let changeVal = ev.target.innerText || ev.target.innerHTML;
  126. if(!this.isIE){
  127. ev.target.innerText?(ev.target.innerText = ''):(ev.target.innerHTML = '');
  128. }
  129. handleLabelEdit && handleLabelEdit({ikey,changeVal,type:boxMark});
  130. }
  131. handledbClick(e){
  132. const {value,id,handleDbclick,patId} = this.props;
  133. clearTimeout(this.state.timer);//取消延时的单击事件
  134. //e.preventDefault();
  135. if(value&&value.trim()) {//有选中值的标签才能双击编辑
  136. this.setState({
  137. editable: true
  138. });
  139. };
  140. //失焦关闭编辑状态
  141. setTimeout(()=>{
  142. e.target.focus();
  143. })
  144. handleDbclick&&handleDbclick({id:patId||id});
  145. }
  146. handleInnerInp(i,val){
  147. const {ikey,boxMark,handleSaveInp} = this.props;
  148. let vals = this.state.texts;
  149. vals[i].value=val;
  150. this.setState({
  151. texts:vals
  152. });
  153. handleSaveInp({values:vals,ikey,boxMark});
  154. }
  155. parseInputDom(){
  156. const {value,placeholder} = this.props;
  157. const {texts} = this.state;
  158. let temp='',list=[];
  159. for(let i in texts){
  160. temp = texts[i];
  161. if(typeof temp=='object'){
  162. list.push(<InputComp handleInp={this.handleInnerInp} editable={true} index={i} value={temp.value}></InputComp>);
  163. }else{
  164. list.push(<span>{temp}</span>);
  165. }
  166. }
  167. /*if(value&&value.indexOf(config.radioOptionPer)!=-1){
  168. let arr = [],inpIndex='';
  169. let list = value.split(config.radioOptionPer);
  170. list.map((it,i)=>{
  171. arr.push(<InputComp value={it}></InputComp>);
  172. inpIndex = (i+1)*2-1;
  173. if(i!=list.length-1){
  174. arr.push(<InputComp handleInp={this.handleInnerInp} editable={true} index={inpIndex}></InputComp>);
  175. }
  176. });
  177. return arr;
  178. }*/
  179. return list;
  180. }
  181. render(){
  182. const {data,show} = this.props;
  183. const {boxLeft,boxTop} = this.state;
  184. return <div className={style['container']} ref = {this.$cont}>
  185. <div className={this.getClass()}
  186. onBlur={this.handleEditLabel}
  187. contentEditable={this.state.editable}
  188. onDoubleClick={this.handledbClick}
  189. onClick={(e)=>this.handleShow(e,true)}
  190. onkeydown={handleEnter}>
  191. {this.parseInputDom()}
  192. </div>
  193. <DropList onSelect={this.handleSelect} data={data} left={boxLeft} top={boxTop} show={show}/>
  194. </div>
  195. }
  196. }
  197. //单选项中的输入框
  198. class InputComp extends Component{
  199. constructor(props){
  200. super(props);
  201. this.handleBlur = this.handleBlur.bind(this);
  202. }
  203. handleBlur(e){
  204. e.stopPropagation();
  205. const text = e.target.innerText;
  206. const {handleInp,index} = this.props;
  207. e.target.innerText = '';
  208. handleInp(index,text);
  209. }
  210. render(){
  211. const {editable,value} = this.props;
  212. return editable?<span contentEditable={true}
  213. className={style['inner-inp']}
  214. onClick={(e)=>{e.stopPropagation()}}
  215. onBlur={this.handleBlur}>{value}</span>:<span>{value}</span>
  216. }
  217. }
  218. export default RadioInpDrop;