211 lines
6.8 KiB
JavaScript
211 lines
6.8 KiB
JavaScript
import React ,{ useState , useEffect , useRef } from 'react';
|
||
import { findDOMNode } from 'react-dom';
|
||
import { Dropdown , Menu , Input , message} from 'antd';
|
||
import { getImageUrl } from 'educoder';
|
||
|
||
const { Search } = Input;
|
||
/**
|
||
*
|
||
* @param {placeholder} placeholder:默认显示内容(为空时)
|
||
* @param {editFlag} editFlag:是否有编辑权限
|
||
* @param {searchFlag} searchFlag:是否显示搜索框
|
||
* @param {selectValueList} selectValueList:将选中的list保存
|
||
* @param {searchFunc} searchFunc:搜索方法
|
||
* @param {onAdd} onAdd:标记管理
|
||
* @param {headImg} headImg:是否显示头像
|
||
* @param {menus} menus:下拉列表
|
||
* @param {chooseFunc} chooseFunc:选择下拉列表
|
||
* @param {double} double:undefined为单选,有值就是最多选的数量
|
||
* @param {colorFlag} colorFlag:选中值需根据颜色显示背景
|
||
* @param {mustFlag} mustFlag:必须选择一个
|
||
* @param {removeFlag} removeFlag:移除按钮
|
||
* @returns
|
||
*/
|
||
function DropMenu({
|
||
placeholder ="未设置",
|
||
editFlag,
|
||
searchFlag,
|
||
selectValueList,
|
||
searchFunc,
|
||
onAdd,
|
||
headImg,
|
||
menus,
|
||
chooseFunc,double,colorFlag,mustFlag,removeFlag
|
||
}){
|
||
const [ visible , setVisible ] = useState(false);
|
||
const [ searchValue , setSearchValue ]= useState(undefined);
|
||
const [ valuesId , setValuesId ] = useState([]);
|
||
const [ valuesName , setValuesName ] = useState([]);
|
||
|
||
const refFa = useRef(null);
|
||
const refBox = useRef(null);
|
||
|
||
|
||
// 根据选中的列表循环出id数组
|
||
useEffect(()=>{
|
||
if(selectValueList && selectValueList.length > 0 ){
|
||
renderSelectList(selectValueList);
|
||
}else{
|
||
setValuesId([])
|
||
}
|
||
},[selectValueList])
|
||
|
||
function renderSelectList(list){
|
||
let a = list && list.length > 0 && list.map((i,k)=>{
|
||
return i.id ? i.id.toString() : i.name
|
||
})
|
||
setValuesId(a);
|
||
setValuesName(list);
|
||
}
|
||
|
||
useEffect(() => {
|
||
document.addEventListener('click', clickMe , false);
|
||
}, [])
|
||
|
||
const clickMe = ({ target }) => {
|
||
// 查找父组件
|
||
const faComponent = findDOMNode(refFa.current);
|
||
const boxComponent = findDOMNode(refBox.current);
|
||
if (faComponent && boxComponent) {
|
||
const isChild = faComponent.contains(target);
|
||
const isBox = boxComponent.contains(target);
|
||
if(!isChild && !isBox){
|
||
setVisible(false);
|
||
}
|
||
}
|
||
}
|
||
// 搜索
|
||
function changeSearchvalue(e){
|
||
setSearchValue(e.target.value);
|
||
searchFunc(e.target.value);
|
||
}
|
||
|
||
function chooseMenu(i){
|
||
let list = selectValueList||[];
|
||
let re = [];
|
||
re = list && list.length > 0 ? list:[];
|
||
let filter = [];
|
||
if(i.id){
|
||
filter = list.filter(j=>j.id === i.id);
|
||
}else{
|
||
filter = list.filter(j=>j.name === i.name);
|
||
}
|
||
if(filter && filter.length > 0){
|
||
if(!mustFlag){
|
||
if(i.id){
|
||
re = list.filter(j=>j.id !== i.id);
|
||
}else{
|
||
re = list.filter(j=>j.name !== i.name);
|
||
}
|
||
renderSelectList(re);
|
||
chooseFunc(re);
|
||
!double && setVisible(false);
|
||
}else{
|
||
setVisible(false);
|
||
}
|
||
}else{
|
||
if(double && (selectValueList && selectValueList.length >= double)){
|
||
message.info(`最多只能添加${double}个${placeholder}`);
|
||
return;
|
||
}
|
||
if(double){
|
||
re.push(i);
|
||
}else{
|
||
re = [i];
|
||
setVisible(false);
|
||
}
|
||
renderSelectList(re);
|
||
chooseFunc(re);
|
||
}
|
||
}
|
||
|
||
function showRemoveFunc(item){
|
||
let l = selectValueList ;
|
||
l = l.filter(i=>(i.id ? i.id.toString() : i.name) !== item.toString());
|
||
renderSelectList(l);
|
||
chooseFunc(l);
|
||
}
|
||
|
||
function renderNames(nameArrs){
|
||
return <React.Fragment>
|
||
{
|
||
nameArrs && nameArrs.length>0?
|
||
nameArrs.map((i,k)=>{
|
||
return(
|
||
<p style={{display:"flex",alignItems:"center"}} className={removeFlag?"removeFlag":''}>
|
||
{i.image_url && <img src={getImageUrl(i.image_url)} alt="" width="28px" height="28px" style={{borderRadius:"50%",marginTop:"5px"}} className="mr5"/>}
|
||
{
|
||
colorFlag ?
|
||
(
|
||
colorFlag === "2" ?
|
||
<span className={"colorsquare task-hide"} style={{backgroundColor:`${i.color}`}}>{i.name}</span>
|
||
:
|
||
<span className={"colorsborder task-hide"} style={{borderColor:`${i.color}`,color:`${i.color}`}}>{i.name}</span>
|
||
)
|
||
:
|
||
<span className={"task-hide"}>{i.name}</span>
|
||
}
|
||
{ removeFlag && <a className="removeicon" onClick={()=>showRemoveFunc(i.id || i.name)}><i className="iconfont icon-shanchu8 font-14"></i></a>}
|
||
</p>
|
||
)
|
||
})
|
||
:<span>{placeholder}</span>
|
||
}
|
||
</React.Fragment>
|
||
}
|
||
return(
|
||
<li className='dropliComponent'>
|
||
<span>
|
||
{placeholder}
|
||
{!editFlag &&
|
||
<a ref={refBox} onClick={()=>setVisible(visible ? false : true)}>
|
||
<i className="iconfont icon-a-bianji12 font-13" style={{color:"#898d9d"}}></i>
|
||
</a>
|
||
}
|
||
</span>
|
||
<Dropdown
|
||
visible={visible}
|
||
overlayClassName={"overlayStyle"}
|
||
placement="bottomLeft"
|
||
trigger={['click']}
|
||
overlay={
|
||
<div ref={refFa}>
|
||
{ searchFunc &&
|
||
<div className="searchbox">
|
||
<Search
|
||
placeholder={`搜索${placeholder}`}
|
||
value={searchValue}
|
||
onChange={changeSearchvalue}
|
||
style={{marginRight:"18px"}}
|
||
/>
|
||
</div>
|
||
}
|
||
{
|
||
menus && menus.length >0?
|
||
<Menu className="piecemenu" selectedKeys={valuesId}>
|
||
{
|
||
menus.map((i,k)=>{
|
||
return(
|
||
<Menu.Item key={i.id || i.name} onClick={()=>chooseMenu(i)}>
|
||
{ headImg && <img src={getImageUrl(i.image_url)} alt="" width="22px" className="mr5 radius"/>}
|
||
{i.color && <span style={{backgroundColor:i.color}} className="colorpiece"></span>}
|
||
<span className="task-hide">{i.name}</span>
|
||
</Menu.Item>
|
||
)
|
||
})
|
||
}
|
||
</Menu>
|
||
:
|
||
<div className="menusEmpty">
|
||
<p>{searchValue ? <span>暂无{placeholder}“{searchValue}”</span>: `暂无${placeholder}`}</p>
|
||
</div>
|
||
}
|
||
{ onAdd && <div className="pl35 pr20 pb20"><a className="color-blue font-15" onClick={()=>{setVisible(false);onAdd()}}><i className="iconfont icon-a-bianji12 font-14 mr5"></i>创建标记</a></div>}
|
||
</div>
|
||
}>
|
||
<div className={selectValueList && selectValueList.length > 0 ? "operatevalue color-grey-3":"operatevalue"}>{renderNames(selectValueList)}</div>
|
||
</Dropdown>
|
||
</li>
|
||
)
|
||
}
|
||
export default DropMenu; |