index.jsx 7.6 KB

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