|
@@ -0,0 +1,223 @@
|
|
|
+import React,{Component} from 'react';
|
|
|
+import {handleEnter,getPageCoordinate,windowEventHandler} from '@utils/tools.js';
|
|
|
+import {DropList} from '@commonComp';
|
|
|
+import config from '@config/index';
|
|
|
+import style from "./index.less";
|
|
|
+import $ from "jquery";
|
|
|
+
|
|
|
+/****
|
|
|
+ * 单选下拉,选项带输入
|
|
|
+ * author:zn@2019-3.18
|
|
|
+ * 接收参数:
|
|
|
+ * placeholder:灰显文字
|
|
|
+ * data:下拉内容数据
|
|
|
+ * handleSelect:选中事件
|
|
|
+ * prefix:前缀
|
|
|
+ * suffix:后缀
|
|
|
+ *
|
|
|
+ * ***/
|
|
|
+
|
|
|
+class RadioInpDrop extends Component{
|
|
|
+ constructor(props){
|
|
|
+ super(props);
|
|
|
+ this.state={
|
|
|
+ editable:false,
|
|
|
+ timer:null,
|
|
|
+ boxLeft:0,
|
|
|
+ boxTop:0,
|
|
|
+ tmpScroll:0,
|
|
|
+ tmpTop:0,
|
|
|
+ texts:props.vals||{0:props.value||props.placeholder}
|
|
|
+ };
|
|
|
+ this.$cont = React.createRef();
|
|
|
+ this.isIE = navigator.appName=="Microsoft Internet Explorer" && navigator.appVersion.split(";")[1].replace(/[ ]/g,"")=="MSIE8.0";
|
|
|
+ this.handleSelect = this.handleSelect.bind(this);
|
|
|
+ this.handleShow = this.handleShow.bind(this);
|
|
|
+ this.handledbClick = this.handledbClick.bind(this);
|
|
|
+ this.handleEditLabel = this.handleEditLabel.bind(this);
|
|
|
+ this.parseInputDom = this.parseInputDom.bind(this);
|
|
|
+ this.handleInnerInp = this.handleInnerInp.bind(this);
|
|
|
+ }
|
|
|
+ getClass(){
|
|
|
+ const {value,hideTag,placeholder,show} = this.props;
|
|
|
+ const blueBorder = this.state.editable?style['blue-border']:'';
|
|
|
+ if(show){
|
|
|
+ $(this.$cont.current).addClass(style['borderd']);
|
|
|
+ }else{
|
|
|
+ $(this.$cont.current).removeClass(style['borderd']);
|
|
|
+ }
|
|
|
+ if(hideTag){
|
|
|
+ return style['no-tag'];
|
|
|
+ }
|
|
|
+ if(value){
|
|
|
+ return blueBorder?style['selected-tag']+' '+blueBorder:style['selected-tag'];
|
|
|
+ }
|
|
|
+ return style['tag'];
|
|
|
+ }
|
|
|
+ handleSelect(item){
|
|
|
+ const {handleSelect,ikey,mainSaveText,value,placeholder} = this.props;
|
|
|
+ let vals = {}, inx = 0;
|
|
|
+ if(!item){
|
|
|
+ handleSelect&&handleSelect({ikey}); //清空
|
|
|
+ this.setState({
|
|
|
+ texts:{0:placeholder}
|
|
|
+ });
|
|
|
+ return ;
|
|
|
+ }
|
|
|
+ const arr = item.name.split(config.radioOptionPer);
|
|
|
+ arr.map((it,i)=>{
|
|
|
+ inx = (i+1)*2-2;
|
|
|
+ vals[inx] = it;
|
|
|
+ if(i!=arr.length-1){
|
|
|
+ vals[+inx+1]={value:'',index:+inx+1}
|
|
|
+ };
|
|
|
+ });
|
|
|
+ this.setState({
|
|
|
+ texts:vals
|
|
|
+ });
|
|
|
+ handleSelect&&handleSelect({ikey,id:item.id,values:vals,mainSaveText});
|
|
|
+ }
|
|
|
+ handleShow(e){
|
|
|
+ //e.stopPropagation();
|
|
|
+ const {handleShow,ikey,id,patId} = this.props;
|
|
|
+ const that = this;
|
|
|
+ const timer = setTimeout(function(){
|
|
|
+ if (that.state.editable) {//如果处于编辑状态点击不显示下拉框
|
|
|
+ return
|
|
|
+ }else {
|
|
|
+ handleShow && handleShow({ikey,id:patId||id});
|
|
|
+ }
|
|
|
+ },300);
|
|
|
+
|
|
|
+ this.setState({
|
|
|
+ timer,
|
|
|
+ boxLeft:getPageCoordinate(e).boxLeft,
|
|
|
+ boxTop:getPageCoordinate(e).boxTop,
|
|
|
+ tmpScroll: $("#addScrollEvent")[0].scrollTop,
|
|
|
+ tmpTop:getPageCoordinate(e).boxTop
|
|
|
+ });
|
|
|
+ windowEventHandler('scroll',()=>{ //弹窗跟随滚动条滚动或者关闭弹窗
|
|
|
+ let scrollYs = $("#addScrollEvent")[0].scrollTop;
|
|
|
+ this.setState({
|
|
|
+ boxTop:this.state.tmpTop - scrollYs + this.state.tmpScroll
|
|
|
+ })
|
|
|
+ },$("#addScrollEvent")[0])
|
|
|
+ }
|
|
|
+ /*componentDidMount(){ //默认值选中
|
|
|
+ const {data,ikey,handleSelect} = this.props;
|
|
|
+ const selected = data.find((it)=>{
|
|
|
+ return it.selected === undefined&&+it.defaultSelect===1;
|
|
|
+ });
|
|
|
+ if(selected){
|
|
|
+ // const text = selected.labelPrefix+selected.name+selected.labelSuffix;
|
|
|
+ const text = selected.name;
|
|
|
+ handleSelect&&handleSelect({ikey,id:selected.id,text});
|
|
|
+ }
|
|
|
+ }*/
|
|
|
+ handleEditLabel(e){
|
|
|
+ e.stopPropagation();
|
|
|
+ if(!this.state.editable){ //ie8点开下拉未选值存值bug修改
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const {ikey,boxMark,handleLabelEdit} = this.props;
|
|
|
+ this.setState({
|
|
|
+ editable:false
|
|
|
+ });
|
|
|
+ // 更改标签的value值
|
|
|
+ const ev = e || window.event;
|
|
|
+ let changeVal = ev.target.innerText || ev.target.innerHTML;
|
|
|
+ if(!this.isIE){
|
|
|
+ ev.target.innerText?(ev.target.innerText = ''):(ev.target.innerHTML = '');
|
|
|
+ }
|
|
|
+ handleLabelEdit && handleLabelEdit({ikey,changeVal,type:boxMark});
|
|
|
+ }
|
|
|
+ handledbClick(e){
|
|
|
+ const {value,id,handleDbclick,patId} = this.props;
|
|
|
+ clearTimeout(this.state.timer);//取消延时的单击事件
|
|
|
+ //e.preventDefault();
|
|
|
+ if(value&&value.trim()) {//有选中值的标签才能双击编辑
|
|
|
+ this.setState({
|
|
|
+ editable: true
|
|
|
+ });
|
|
|
+ };
|
|
|
+ //失焦关闭编辑状态
|
|
|
+ setTimeout(()=>{
|
|
|
+ e.target.focus();
|
|
|
+ })
|
|
|
+ handleDbclick&&handleDbclick({id:patId||id});
|
|
|
+ }
|
|
|
+ handleInnerInp(i,val){
|
|
|
+ const {ikey,boxMark,handleSaveInp} = this.props;
|
|
|
+ let vals = this.state.texts;
|
|
|
+ vals[i].value=val;
|
|
|
+ this.setState({
|
|
|
+ texts:vals
|
|
|
+ });
|
|
|
+ handleSaveInp({values:vals,ikey,boxMark});
|
|
|
+ }
|
|
|
+ parseInputDom(){
|
|
|
+ const {value,placeholder} = this.props;
|
|
|
+ const {texts} = this.state;
|
|
|
+ let temp='',list=[];
|
|
|
+ for(let i in texts){
|
|
|
+ temp = texts[i];
|
|
|
+ if(typeof temp=='object'){
|
|
|
+ list.push(<InputComp handleInp={this.handleInnerInp} editable={true} index={i} value={temp.value}></InputComp>);
|
|
|
+ }else{
|
|
|
+ list.push(<span>{temp}</span>);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*if(value&&value.indexOf(config.radioOptionPer)!=-1){
|
|
|
+ let arr = [],inpIndex='';
|
|
|
+ let list = value.split(config.radioOptionPer);
|
|
|
+ list.map((it,i)=>{
|
|
|
+ arr.push(<InputComp value={it}></InputComp>);
|
|
|
+ inpIndex = (i+1)*2-1;
|
|
|
+ if(i!=list.length-1){
|
|
|
+ arr.push(<InputComp handleInp={this.handleInnerInp} editable={true} index={inpIndex}></InputComp>);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return arr;
|
|
|
+ }*/
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+ render(){
|
|
|
+ const {data,show} = this.props;
|
|
|
+ const {boxLeft,boxTop} = this.state;
|
|
|
+ return <div className={style['container']} ref = {this.$cont}>
|
|
|
+ <div className={this.getClass()}
|
|
|
+ onBlur={this.handleEditLabel}
|
|
|
+ contentEditable={this.state.editable}
|
|
|
+ onDoubleClick={this.handledbClick}
|
|
|
+ onClick={(e)=>this.handleShow(e,true)}
|
|
|
+ onkeydown={handleEnter}>
|
|
|
+ {this.parseInputDom()}
|
|
|
+ </div>
|
|
|
+ <DropList onSelect={this.handleSelect} data={data} left={boxLeft} top={boxTop} show={show}/>
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//单选项中的输入框
|
|
|
+class InputComp extends Component{
|
|
|
+ constructor(props){
|
|
|
+ super(props);
|
|
|
+ this.handleBlur = this.handleBlur.bind(this);
|
|
|
+ }
|
|
|
+ handleBlur(e){
|
|
|
+ e.stopPropagation();
|
|
|
+ const text = e.target.innerText;
|
|
|
+ const {handleInp,index} = this.props;
|
|
|
+ e.target.innerText = '';
|
|
|
+ handleInp(index,text);
|
|
|
+ }
|
|
|
+ render(){
|
|
|
+ const {editable,value} = this.props;
|
|
|
+ return editable?<span contentEditable={true}
|
|
|
+ className={style['inner-inp']}
|
|
|
+ onClick={(e)=>{e.stopPropagation()}}
|
|
|
+ onBlur={this.handleBlur}>{value}</span>:<span>{value}</span>
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+export default RadioInpDrop;
|