index.jsx 6.9 KB

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