Chamani Shiranthika
Chamani Shiranthika

Reputation: 73

How to drag and drop element if only item do not exist in Array - React DND ES6

I am working on a project that involves React DND ES6. I want to drag elements from the lest panel and drop them in respective boxes in right.

I have done this by dragging the element from left panel and implementing in to an Array. But the problem here is same item is able to add in to the array as follows.

I want to make it such that If item is already dragged to a particular box, dragging again that item from left panel and drop in correct box should not work. In a situation like that it should display alert box saying like ‘Item _name’ is already dragged to the ‘box_name’.

I tried achieve this adding following code before setBins method. But was not successful.

 if (!lastDroppedItem.includes(item)){  setBins(
         update(bins, {
          [index]: {
            lastDroppedItem: {
                          $push: [item],   
            },
          },
        })       
      )
    },
    [droppedBoxNames , bins],   )

Please find my codes in codesandbox here: - https://codesandbox.io/s/reactdndapp-2vz82

Please do help. Thank You.

Upvotes: 1

Views: 1335

Answers (2)

Ajeet Shah
Ajeet Shah

Reputation: 19823

You can have one more property - droppedItems for each bin which holds all the dropped items so far, an example:

{
  dname: 'BIN 1',
  accepts: [ItemTypes.BOOK, ItemTypes.BOTTLE, ItemTypes.FOOD],
  lastDroppedItem: {},
  droppedItems: [],
},

And check if the item is already in bin:

function isBoxAlreadyInBin(bins, index, name) {
  const droppedItems = bins[index].droppedItems || [];
  return droppedItems.some(item => item.name === name);
}

const handleDrop = useCallback(
(index, item) => {
  const { name } = item;

  setDroppedBoxNames(
    update(droppedBoxNames, name ? { $push: [name] } : { $push: [] })
  );

  if (isBoxAlreadyInBin(bins, index, name)) {
    alert(`${name} already in bin ${index}`);
  } else {
    setBins(
      update(bins, {
        [index]: {
          lastDroppedItem: {
            $set: item
          },
          droppedItems: {
            $push: [item]
          }
        }
      })
    );
  }
},
[droppedBoxNames, bins]
);

Hope this helps!

Upvotes: 2

Akinjiola Toni
Akinjiola Toni

Reputation: 678

You need to do search the array if an instance of the object you are about to drop exists in the bin first before you update it by calling the setBin method, otherwise you can ignore or trigger a notification.

Here I used the javascript array find method to check if a similar object exists in the bin.

if (!bins[index].lastDroppedItem.find(x => x.name === item.name)) {
    setBins(
        update(bins, {
            [index]: {
              lastDroppedItem: {
                $push: [item]
              }
            }
        })
    );
}

Upvotes: 2

Related Questions