拖放功能问题:框未放置在正确的列中

问题描述 投票:0回答:1

在下面的代码中,我显示了一个每周日历,如下所示:

当我将这些可拖动框从一个日期拖放到另一个日期时,例如,如果我将第 8 列中的 Morooka 从星期二 9 日拖动到星期日 7 日,它会将其放入第一列。其他可拖动框也会发生同样的情况;如果我将它们从第 1 列的第 9 个放到第 6 列的第 10 个,它们仍然会出现在第 1 列中。

我希望拖拽框被拖放到我释放它的列中。因此,如果我将其放入第 5 列,它应该保留在第 5 列。但是,目前,所有内容都被放入第 1 列。有什么方法可以解决这个问题吗?

当拖动框被放下时,我尝试在 console.log 中进行打印,它似乎可以识别正确的列并正确打印日期和时间段。然而,它仍然没有落入正确的列

    import React, { useState, useRef } from "react";
import { startOfWeek, endOfWeek, format, addDays, subDays, set } from "date-fns";
import axios from 'axios';

import { fetchCustomers } from '../../api/customer';
const DraggableBox = ({
  day,
  name: initialName,
  suburb: initialSuburb,
  calendarData,
  setCalendarData,
  changeName,
  setChangeName,
  changeSuburb,
  setChangeSuburb,
  setChangeDay,
  setChangeData,
  orderData,
  setOrderData,
  timeSlotIndex,
}) => {
  const [showTooltip, setShowTooltip] = useState(false);
  const boxRef = useRef(null);

  const filteredOrders = orderData.order.filter(
    (order) => new Date(order.RequiredDateAndTime).getDate() === parseInt(day)
  );

  const handleDragStart = (e) => {
    setShowTooltip(false);
    setChangeData(filteredOrders[timeSlotIndex]);
    boxRef.current.classList.add("dragging");
  };

  const handleDragEnd = () => {
    boxRef.current.classList.remove("dragging");
  };

  const handleDragOver = (e) => {
    e.preventDefault();
  };
     

  return (
    <div
      className="drag-box"
      ref={boxRef}
      draggable
      onDragStart={handleDragStart}
      onDragEnd={handleDragEnd}
      onDragOver={handleDragOver}
      onMouseEnter={() => setShowTooltip(true)}
      onMouseLeave={() => setShowTooltip(false)}
      style={{
        width: "70px",
        height: "70px",
        textAlign: "center",
        backgroundColor: "#F5F5F5",
        color: "#333333",
        marginTop: "0px",
        position: "relative",
        cursor: "move",
        fontSize: "10px",
      }}
      data-day={day}
      data-name={initialName}
    >
      <div>
        {filteredOrders[timeSlotIndex] && (
          <div key={timeSlotIndex}>
            <p>{filteredOrders[timeSlotIndex].DelCity}</p>
          </div>
        )}
      </div>
    </div>
  );
};




const RunSheetPreview = ({
orderData,  
setOrderData,
  selectedDate,

  initialName,
  initialSuburb,
  setShowTooltip,
  }) => {
  const boxRef = useRef(null);
  const [changeName, setChangeName] = useState("");
  const [changeDay, setChangeDay] = useState(null);
  const [changeData, setChangeData] = useState(null);
 
  const [changeSuburb, setChangeSuburb] = useState(null);
  const [selectedDateState, setSelectedDate] = useState(new Date());
  const handleNextWeek = () => {

    setSelectedDate(addDays(selectedDateState, 7));
  };

  const handlePreviousWeek = () => {
    setSelectedDate(subDays(selectedDateState, 7));
  };
  const formatDate = (date) => {
  const dateVal = new Date(date);
  const year = dateVal.getFullYear();
  const month = String(dateVal.getMonth() + 1).padStart(2, "0");
  const day = String(dateVal.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
};
const handleDragOver = (e) => {
  e.preventDefault();
};

const handleDrop = (e, timeSlotIndex, dayOfMonth, year, month) => {
  e.preventDefault();
  e.stopPropagation();
  
  let d = { ...changeData };
  d = new Date(d.OrderDate);
  
  const number = e.target.tabIndex.toString();
  console.log("Number:", number);
  
  const currentYear = e.target.getAttribute('data-year');
  let currentMonth = e.target.getAttribute('data-month');
  
  // Log the day, month, and year
  console.log("Day:", dayOfMonth);
  
  // Format the month with leading zero if it's a single digit
  currentMonth = currentMonth.padStart(2, "0");
  console.log("Month:", currentMonth);
  
  console.log("Year:", currentYear);
  
  // Format the day with leading zero
  const formattedDay = dayOfMonth.toString().padStart(2, "0");
  
  const formattedDate = `${currentYear}-${currentMonth}-${formattedDay}`;
  console.log("Formatted Date:", formattedDate);
  
  d.setDate(dayOfMonth);
  d.setMonth(currentMonth);
  d.setFullYear(currentYear);
  d = d.toISOString();
  
  let fi = { ...changeData };
  fi.OrderDate = d;
  fi.RequiredDateAndTime = d;
  
  let newDate = new Date(changeData.OrderDate);
  newDate = new Date(currentYear, currentMonth, dayOfMonth, newDate.getHours(), newDate.getMinutes(), newDate.getSeconds());

  // Update the order data
  let newOrderData = orderData.order.filter(item => item !== changeData);

  // Update the order date for the dragged item to its new position
  changeData.OrderDate = newDate.toISOString();
  changeData.RequiredDateAndTime = newDate.toISOString();
  const timeSlot = `${timeSlotIndex + 1}`;
  console.log("Updated changeData:", changeData); // Log the updated changeData

  console.log("Time Slot:", timeSlot);

  // Push the updated dragged item to the new position
  newOrderData.push({ ...changeData, timeSlot });
  console.log("Updated newOrderData:", newOrderData);



  setCalendarData(newOrderData);
};


// Remove the filter based on selectedDate
const dateStrings = orderData.order.map((listItem) => {
  const date = new Date(listItem.RequiredDateAndTime);
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
});



const initialCalendarData = orderData.order.map((order, index) => {
  const name = order.DelCity;
  const suburb = order.DelPostalCode;
  return {
    day: dateStrings[index], // Use dateStrings array here
    name,
    suburb,
    initialName: name, // Assign the value to initialName
    initialSuburb: suburb, // Assign the value to initialSuburb
  };
});
const [calendarData, setCalendarData] = useState(initialCalendarData);
 
const generateCalendar = () => {
  const startDate = startOfWeek(selectedDateState, { weekStartsOn: 0 });
  const endDate = endOfWeek(selectedDateState, { weekStartsOn: 0 });

  const rows = [];
  let day = startDate;

  while (day <= endDate) {
    const formattedDate = formatDate(day);
    const dateObject = new Date(formattedDate);
    const year = dateObject.getFullYear(); // Extract year (e.g., 2024)
    const month = dateObject.getMonth() + 1;
    const dayName = format(day, "EEEE");
    const dayOfMonth = format(day, "d");

    const isTargetDate = dateStrings.includes(formattedDate);

    const ordersForDay = orderData.order.filter((order) => {
      const orderDate = new Date(order.RequiredDateAndTime).getDate();
      return orderDate === parseInt(dayOfMonth);
    });

    // Find the first available time slot for the current day
    const firstAvailableSlot = ordersForDay.findIndex(
      (order) => !order.isAssigned
    );

    const row = (
      <tr key={day}>
        <td className="calendar-cell">
          <div className="day-name">{dayName}</div>
          <div className="day-number">{dayOfMonth}</div>
        </td>
        {[...Array(15)].map((_, index) => (
          <td
            key={index}
            className={`grid-cell`}
            data-has-data={ordersForDay[index] ? "true" : "false"}
          >
            {/* Render DraggableBox only if there is an order for this column */}
            {ordersForDay[index] && (
              <DraggableBox
                day={parseInt(dayOfMonth)}
                initialName={ordersForDay[index].DelCity}
                initialSuburb={ordersForDay[index].DelPostalCode}
                calendarData={calendarData}
                setCalendarData={setCalendarData}
                changeName={changeName}
                setOrderData={setOrderData} // Pass the setOrderData function
                setChangeName={setChangeName}
                changeDay={changeDay}
                setChangeDay={setChangeDay}
                changeSuburb={changeSuburb}
                setChangeSuburb={setChangeSuburb}
                setChangeData={setChangeData}
                orderData={orderData}
                timeSlotIndex={index}
              />
            )}
            {!ordersForDay[index] && (
              <p
                style={{
                  height: "40px",
                  width: "60px",
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                }}
                onDragOver={handleDragOver}
                onDrop={(e) =>
                  handleDrop(
                    e,
                    index,
                    parseInt(dayOfMonth),
                    year,
                    month
                  )
                }
                tabIndex={dayOfMonth}
                data-year={year}
                data-month={month}
              ></p>
            )}
          </td>
        ))}
      </tr>
    );

    rows.push(row);

    day = addDays(day, 1);
  }

  return rows;
};

      
     
return (
  <div>
  <div className="delivery-schedule-heading">
      <h2 style={{ color: "", margin: "0 0px 0 0px", textAlign: "left" }}></h2>
      <div style={{ textAlign: "left", margin: "0 0px 0 0px" }}>
  <h2 style={{ margin: 0, color: "#08315b", fontWeight: "bold" }}>
    Delivery Schedule : {format(startOfWeek(selectedDateState), "MMMM d")} -{" "}
    {format(endOfWeek(selectedDateState), "MMMM d, yyyy")}
  </h2>
</div>

      <div style={{ textAlign: "right" }}>
          {/* Button for moving to the previous week */}
          <button onClick={handlePreviousWeek}>&lt; Previous Week</button>
          {/* Button for moving to the next week */}
          <button onClick={handleNextWeek}>Next Week &gt;</button>
        </div>
    </div>
  
<div className="calendar-container">
<table className="calendar-table">
<thead>
<tr>
<th>{/* Empty header cell for labels */}</th>

{[...Array(15)].map((_, index) => (
<th key={index}>{index + 1}</th>
))}

</tr>
</thead>
<tbody>
{generateCalendar()}
</tbody>
</table>
</div>
</div>
);
};

export default RunSheetPreview;
css reactjs drop-down-menu menu submenu
1个回答
0
投票

问题似乎是您使用ordersForDay索引来标识时间段,而不是使用您自己的timeSlot属性。

当您在 JavaScript 中过滤数组时,它不会维护其原始索引。这就是为什么所有订单最终都在起始列中“分组在一起”,而不是像您期望的那样留下空白。

而不是像您在代码中那样按天过滤:

const ordersForDay = orderData.order.filter((order) => {
    const orderDate = new Date(order.RequiredDateAndTime).getDate();
    return orderDate === parseInt(dayOfMonth);
});

您可以在行创建中按时间段过滤

{[...Array(15)].map((_, index) => {
    const ordersForTimeSlot = orderData.order.filter((order) => {
        const orderDate = new Date(order.RequiredDateAndTime).getDate();
        return orderDate === parseInt(dayOfMonth) && order.timeSlot == index;
    });
    return (<td ...

然后你可以检查该时间段是否有订单,将其显示为 DraggableBox:

{ordersForTimeSlot[0] && (
    <DraggableBox ...

此代码未经测试,但我希望这可以帮助您指出正确的方向!

© www.soinside.com 2019 - 2024. All rights reserved.