Как отфильтровать списки перетаскивания, когда есть больше 2 контейнеров отбрасывания
У меня есть следующий код перетаскивания, часть кода модифицирована, я получил его ЗДЕСЬ. Посмотрите на код ниже:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import './beautifulDnd-Cal.css';
const generateDays = ( noofdays ) => {
let daysinaweek = ['Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' , 'Sat' , 'Sun'];
return daysinaweek.splice(0 , noofdays ).map( ( e , i ) => { return {'id' : i , 'day' : e} } )
}
// fake data generator
const getItems = (count, offset = 0) =>
Array.from({ length: count }, (v, k) => k).map(k => ({
id: `item-${k + offset}`,
content: `item ${k + offset}`
}));
// a little function to help us with reordering the result
const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
/**
* Moves an item from one list to another list.
*/
const move = (source, destination, droppableSource, droppableDestination) => {
const sourceClone = Array.from(source);
const destClone = Array.from(destination);
const [removed] = sourceClone.splice(droppableSource.index, 1);
destClone.splice(droppableDestination.index, 0, removed);
const result = {};
result[droppableSource.droppableId] = sourceClone;
result[droppableDestination.droppableId] = destClone;
return result;
};
const grid = 8;
const getItemStyle = (isDragging, draggableStyle) => ({
// some basic styles to make the items look a bit nicer
userSelect: 'none',
padding: grid * 2,
margin: `0 0 ${grid}px 0`,
// change background colour if dragging
background: isDragging ? 'lightgreen' : 'grey',
// styles we need to apply on draggables
...draggableStyle
});
const getListStyle = isDraggingOver => ({
background: isDraggingOver ? 'lightblue' : 'lightgrey',
padding: grid,
width: 250,
display: 'inline-block',
verticleAlign: 'top'
});
class Actionsnowball extends Component {
state = {
items: getItems(5),
selected: getItems(0,5),
caldays : generateDays(1)
};
/**
* A semi-generic way to handle multiple lists. Matches
* the IDs of the droppable container to the names of the
* source arrays stored in the state.
*/
id2List = {
droppable: 'items',
droppable2: 'selected'
};
/*
below function will return an array like so --> (5) [{…}, {…}, {…}, {…}, {…}]
*/
getList = id => this.state[this.id2List[id]];
onDragEnd = result => {
console.log(result);
const { source, destination } = result;
// dropped outside the list
if (!destination) {
return;
}
if (source.droppableId === destination.droppableId) {
const items = reorder(
this.getList(source.droppableId),
source.index,
destination.index
);
let state = { items };
if (source.droppableId === 'droppable2') {
state = { selected: items };
}
this.setState(state);
} else {
const result = move(
this.getList(source.droppableId),
this.getList(destination.droppableId),
source,
destination
);
this.setState({
items: result.droppable,
selected: result.droppable2
});
}
};
// Normally you would want to split things out into separate components.
// But in this example everything is just done in one place for simplicity
render() {
return (
<DragDropContext onDragEnd={this.onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
className="eventSidebar"
>
{this.state.items.map((item, index) => (
<Draggable
key={item.id}
draggableId={item.id}
index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
<div className="reactbeautifulCalender">
{ this.state.caldays.map( (item, index) => (
<Droppable
droppableId="droppable2"
key={ item.id } >
{(provided, snapshot) => (
<div
ref={provided.innerRef}
style={getListStyle(snapshot.isDraggingOver)}
className="days">
{this.state.selected.map((item, index) => (
<Draggable
key={item.id}
draggableId={item.id}
index={index}>
{(provided, snapshot) => (
<div
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
style={getItemStyle(
snapshot.isDragging,
provided.draggableProps.style
)}>
{item.content}
</div>
)}
</Draggable>
))}
{provided.placeholder}
</div>
)}
</Droppable>
))}
</div>
</DragDropContext>
);
}
}
export default Actionsnowball;
// Put the things into the DOM!
//ReactDOM.render(<App />, document.getElementById('root'));
Когда вы перемещаете элемент из одного потерянного в другой, вызывается следующая функция (функция move
, если бы вы переместили элемент со списком, вместо этого была бы вызвана функция переупорядочения).
const move = (source, destination, droppableSource, droppableDestination) => {
const sourceClone = Array.from(source);
const destClone = Array.from(destination);
const [removed] = sourceClone.splice(droppableSource.index, 1);
destClone.splice(droppableDestination.index, 0, removed);
const result = {};
result[droppableSource.droppableId] = sourceClone;
result[droppableDestination.droppableId] = destClone;
return result;
};
Как вы можете видеть, вышеупомянутая функция будет работать нормально, пока есть два списка, мой вопрос, что происходит, когда существует более двух списков? Как вы будете фильтровать элементы? Конечно, функция может быть изменена, чтобы дополнительно фильтровать элементы из более чем двух списков, но является ли это лучшим способом сделать это?
PS тогда это скорее вопрос архитектуры, как мне это сделать.