0

To start, for this project I use react-beautiful-dnd, Chakra UI, and Next.js. This is the link to the video that displays the problem: https://youtu.be/8maSmqahjfw. I've tried doing ondragupdate, ondragstart, and ondragend, various reordering and it still didn't fully work. I wonder if it is because I am also using Chakra UI or that my flex chakra item is just very large with lots of content. This is my code for the draggable, where I loop and add the links:

setLinks((prevRows) => [
            ...prevRows,

            <Draggable
              key={element.order}
              draggableId={`draggable-${element.order}`}
              index={element.order}
            >
              {(provided, snapshot) => (
                <Flex
                  direction={"column"}
                  padding={3}
                  justifyContent={"center"}
                  alignItems={"center"}
                  width={{ base: "95%", md: "70%", lg: "70%" }}
                  backgroundColor={"#fff"}
                  boxShadow={"0px 0px 3px 0px #b0b0b0"}
                  borderRadius={10}
                  // ref={provided.innerRef}
                  {...provided.draggableProps}
                  {...provided.dragHandleProps}
                  ref={provided.innerRef}
                  //opacity={snapshot.isDragging ? 0.5 : 1}
                >
                  <Flex
                    width={"100%"}
                    justifyContent={"space-between"}
                    alignItems={"center"}
                  >
                    <Flex
                      alignItems={"center"}
                      justifyContent={"center"}
                      gap={1}
                    >
                      <Button
                        colorScheme="transparent"
                        _hover={{
                          cursor: "grab",
                          //backgroundColor: "#efefef",
                        }}
                        _active={{
                          cursor: "grabbing",
                        }}
                      >
                        <DragHandleIcon color={"black"} />
                      </Button>
                      <Flex
                        position="relative"
                        w={{
                          base: "100px",
                          md: "120px",
                          lg: "140px",
                        }}
                        h={{ base: "60px", md: "80px", lg: "100px" }}
                        bg="transparent"
                        borderRadius="none"
                        alignItems={"center"}
                        justifyContent={"center"}
                        overflow="hidden"
                        border={"1px dashed black"}
                      >
                        {/* {"Url " + console.log(urls[i])} */}
                        {urls[i] != null ? (
                          <>
                            <Image
                              src={urls[i]}
                              alt="Selected Image"
                              objectFit="cover"
                              w="100%"
                              h="100%"
                            />
                          </>
                        ) : (
                          <Box
                            //p={6}
                            textAlign="center"
                            backgroundColor={"none"}
                          >
                            <Text fontSize={"10pt"} fontWeight={700}>
                              No Image
                            </Text>
                          </Box>
                        )}
                      </Flex>
                      <Flex
                        direction={"column"}
                        alignItems={"flex-start"}
                        justifyContent={"center"}
                        width={"100%"}
                      >
                        <Input
                          value={element.title}
                          border={"none"}
                          fontSize={"12pt"}
                          //maxWidth={"100%"}
                          //isReadOnly={!selectedInput || selectedInput !== input}
                          isReadOnly={true}
                          //onFocus={() => setSelectedOrder(i)}
                        />
                        <Input
                          isReadOnly={true}
                          type={"url"}
                          border={"none"}
                          fontSize={"9pt"}
                          value={element.url}
                          //maxWidth={"100%"}
                        />
                      </Flex>
                    </Flex>
                    <Flex
                      direction={"column"}
                      alignItems={"center"}
                      justifyContent={"center"}
                      gap={5}
                    >
                      <Switch
                        defaultChecked={element.active}
                        value={element.order}
                        onChange={handleCheckboxChange}
                      />
                      <Menu>
                        <MenuButton as={Button} colorScheme="transparent">
                          <Image
                            src="/triple.png"
                            alt={"triple dots"}
                            width={22}
                            height={22}
                          />
                        </MenuButton>
                        <MenuList>
                          <MenuItem onClick={() => takeCharge(element.order)}>
                            Edit
                          </MenuItem>
                          <MenuItem
                            onClick={() => {
                              setDeleteIn(element.order);
                              onOpen4();
                            }}
                          >
                            Delete
                          </MenuItem>
                        </MenuList>
                      </Menu>
                    </Flex>
                  </Flex>
                </Flex>
              )}
            </Draggable>,
          ]);

And this is the code for the dragdropcontext and droppable, I have been also getting some troubles with the provided placeholder as the flex items sometimes stick to each other as shown in the video when I try to drag the other item:

<DragDropContext onDragEnd={onDragEnd}>
              <Droppable droppableId="droppable">
                {(provided, snapshot) => (
                  <Flex
                    direction={"column"}
                    alignItems={"center"}
                    ref={provided.innerRef}
                    {...provided.droppableProps}
                    width={"100%"}
                    height={"100%"}
                    gap={8}
                  >
                    {links}
                    {provided.placeholder}
                  </Flex>
                )}
              </Droppable>
            </DragDropContext>

Finally, this is my ondragend function that I use to reorder all of my elements after drag finished:

const onDragEnd = (result) => {
    if (!result.destination) {
      return;
    }

    const newItems = Array.from(links);
    const [reorderedItem] = newItems.splice(result.source.index, 1);
    newItems.splice(result.destination.index, 0, reorderedItem);
    setLinks(newItems);
  };
mrtomblue
  • 118
  • 1
  • 11

1 Answers1

0

Try disabling "reactStrictMode" as it may cause some errors as the drag and drop mechanism is executed 2 times.

Best, Grzegorz

bergrz
  • 1
  • 2
  • I did, (don't have react strict mode in my next.config.js file code) and it still doesn't work – Benjamin Sloutsky Aug 06 '23 at 17:42
  • I understand, you can also try to implement it like in "Simple vertical list" example in the project repository https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/about/examples.md – bergrz Aug 06 '23 at 17:55