index.jsx 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. import react from "react";
  2. import style from "./index.less";
  3. import $ from 'jquery';
  4. import classNames from 'classnames';
  5. import {handleEnter,isIE,filterArr,deepClone,filterDataArr} from '@utils/tools.js';
  6. import {Notify} from '@commonComp';
  7. import config from '@config/index.js';
  8. /**
  9. 单列多选组件(tagtype=1,controlType=2)
  10. 2019-2-20 By_liucf
  11. 参数:
  12. placeholder:标签名
  13. value:标签选中的值
  14. show:是否展示下拉
  15. data:下拉数据
  16. type:标识哪一项数据(1-主诉,2-现病史,3-其他史,4-查体)
  17. **/
  18. class Multiple extends react.Component{
  19. constructor(props){
  20. super(props);
  21. const {seleData,seleId} = deepClone(props.selecteds||[]);
  22. this.state={
  23. editable:false,
  24. timer:null,
  25. labelVal:"",
  26. seleData:seleData||"",
  27. seleId:seleId||[],
  28. boxLeft:null,
  29. boxTop:null
  30. }
  31. this.$div = React.createRef();
  32. this.handleShow = this.handleShow.bind(this);
  33. this.changeToEdit = this.changeToEdit.bind(this);
  34. this.handleSelect = this.handleSelect.bind(this);
  35. this.onChange = this.onChange.bind(this);
  36. this.handleBlur = this.handleBlur.bind(this);
  37. this.handleClear = this.handleClear.bind(this);
  38. this.handleComfirn = this.handleComfirn.bind(this);
  39. }
  40. getClass(){
  41. const {show,value,hideTag} = this.props;
  42. if(show){
  43. $(this.$div.current).addClass(style['borderd']);
  44. }else{
  45. $(this.$div.current).removeClass(style['borderd']);
  46. }
  47. if(value){
  48. return hideTag?style['hide-tag']:style['selected-tag'];
  49. }
  50. return hideTag?'':style['tag'];
  51. }
  52. getListClass(){
  53. let name = style['text-list'];
  54. let isHide = this.props.show?'':style['hide'];
  55. return classNames(style['list'],name,isHide);
  56. }
  57. getSeleStyle(id){
  58. const {seleId} = this.state;
  59. if(seleId.includes(id)){
  60. return style['selected'];
  61. }
  62. return '';
  63. }
  64. handleShow(e){//单击
  65. e&&e.stopPropagation();
  66. let boxLeft = e.pageX -133 + 'px';
  67. let offsetTop = e.target.offsetTop;
  68. const ht = e.target.offsetHeight; //如杂音选中文字有多行时,写死会遮挡
  69. let boxTop = offsetTop + ht +2 + 'px';
  70. this.setState({
  71. boxLeft:boxLeft,
  72. boxTop:boxTop
  73. })
  74. this.setStateInit();
  75. const {ikey,handleShow,placeholder,flag,id,value,tagType,type} = this.props;
  76. const that = this;
  77. clearTimeout(this.state.timer);
  78. this.state.timer = setTimeout(function(){
  79. if (that.state.editable) {//如果处于编辑状态点击不显示下拉框
  80. return
  81. }else{
  82. handleShow&&handleShow({ikey,placeholder,flag,id,value,tagType,type});
  83. }
  84. },300)
  85. }
  86. setStateInit(){//恢复初始选中状态
  87. const {seleData,seleId} = deepClone(this.props.selecteds||[]);
  88. this.setState({
  89. seleData:seleData||"",
  90. seleId:seleId||[],
  91. })
  92. }
  93. changeToEdit(e){//双击
  94. const {value,id,placeholder,handleDbclick,handleHide} = this.props;
  95. let text = e.target.innerText || e.target.innerHTML;
  96. handleHide&&handleHide(); //展开情况下双击收起
  97. // clearTimeout(this.state.timer);//取消延时的单击事件
  98. e.stopPropagation();
  99. if(value&&value.trim()){//有选中值的标签才能双击编辑
  100. this.setState({
  101. labelVal:text,
  102. editable:true
  103. });
  104. e.target.focus();
  105. handleDbclick && handleDbclick({value,id,placeholder});
  106. }
  107. }
  108. handleSelect(e,item){
  109. e&&e.stopPropagation();
  110. let {seleData,seleId} = this.state;
  111. const {name,id} = item;
  112. if(seleId.includes(id)){
  113. seleId.splice(seleId.indexOf(id),1);
  114. seleData = seleData.replace(name,'');
  115. }else{
  116. seleId.push(id);
  117. seleData += name;
  118. }
  119. this.setState({
  120. seleData,
  121. seleId
  122. })
  123. }
  124. onChange(e){
  125. const {mainSaveText,ikey,type,handleLabelChange} = this.props;
  126. const {labelVal,editable} = this.state;
  127. let mainText = filterDataArr(mainSaveText);//主诉字数
  128. if(editable){//避免IE中点击标签也会触发
  129. let val = e.target.innerText || e.target.innerHTML;
  130. if(+type==1){// 主诉字数达到上限时不允许输入
  131. if(mainText.length >= config.limited){
  132. if(val.length > labelVal.length){
  133. e.target.innerText?(e.target.innerText = labelVal):(e.target.innerHTML = labelVal);
  134. Notify.info(config.limitText);
  135. return
  136. }else if(val.length == labelVal.length){
  137. this.setState({
  138. labelVal:val
  139. });
  140. }else{
  141. handleLabelChange && handleLabelChange({ikey,changeVal:val,type});
  142. }
  143. }
  144. }
  145. }
  146. }
  147. handleBlur(e){//修改存值
  148. e.stopPropagation();
  149. const {ikey,type,handleLabelChange} = this.props;
  150. const {editable} = this.state;
  151. const ev = e || window.event;
  152. if(editable){
  153. // 更改标签的value值
  154. let changeVal = ev.target.innerText || e.target.innerHTML;
  155. if(!isIE()){
  156. e.target.innerText?(e.target.innerText = ''):(e.target.innerHTML=''); //避免出现重复输入值
  157. }
  158. handleLabelChange && handleLabelChange({ikey,changeVal,type});
  159. }
  160. this.setState({
  161. editable:false
  162. });
  163. }
  164. handleClear(e){
  165. e&&e.stopPropagation();
  166. this.setState({
  167. seleData:"",
  168. seleId:[]
  169. })
  170. }
  171. handleComfirn(e){
  172. e&&e.stopPropagation();
  173. const {handleConfirm,ikey,order,mainSaveText,value,handleHide,type} = this.props;
  174. const params = Object.assign({},this.state,{ikey,order,mainSaveText,value,type});
  175. handleConfirm&&handleConfirm(params);
  176. handleHide&&handleHide();
  177. }
  178. componentDidMount(){
  179. if(isIE()){
  180. $(this.$div.current).onIe8Input(function(e){
  181. this.onChange(e)
  182. },this);
  183. }
  184. }
  185. render(){
  186. const {placeholder,value,show,data} = this.props;
  187. const {editable,boxTop,boxLeft} = this.state;
  188. return <div className={style["container"]}>
  189. <div className={this.getClass()}
  190. ref={this.$div}
  191. onClick={this.handleShow}
  192. onDoubleClick={this.changeToEdit}
  193. onBlur={this.handleBlur}
  194. onInput={this.onChange}
  195. onkeydown={handleEnter}
  196. contentEditable={editable}>{value||placeholder}</div>
  197. <div className={this.getListClass()} style={{top:boxTop,left:boxLeft}} contentEditable="false">
  198. <ul>
  199. {data&&data.map((it)=>{
  200. return <li onClick={(e)=>this.handleSelect(e,it)} className={this.getSeleStyle(it.id)} title={it.name.length>8?it.name:''}>{it.name&&it.name.length>8?it.name.slice(0,8)+'...':it.name}</li>
  201. })}
  202. <li onClick={this.handleClear} className={style['mClear']}>清空选项</li>
  203. <li onClick={this.handleComfirn} className={style['mConfirm']}>确定</li>
  204. </ul>
  205. </div>
  206. </div>
  207. }
  208. }
  209. export default Multiple;