jQuery UI 日历可拖放

jQuery UI Droppable and Draggable for Calendar

我有一个运行良好的日历包,但我想用 jQueryUI 中的可拖放元素构建另一个日历包ui。刚开始,但是这里有一个fiddle和下面的代码。有几个问题。如果我将 containment 设置为 parent,你不能 apparently 拖动到一个可放置的项目并且我不清楚 jquery 如何放置放置的元素(因为 children 他们被拖到的元素或者只是相对于原始元素的绝对位置 parent).

我或许可以编写一个函数来检查同一日历组的重叠约会,但我真的很想拖放元素,使它们成为目标元素的 children。

该代码段基本上创建了一个新元素,用户可以在该元素中单击一天并将该元素绝对相对于 parent 定位,并且它允许在 parent 内部拖动和调整大小,但我想拖放到另一天,并使拖放的元素成为目标的 child。我还必须弄清楚如何获得 parent 的偏移量和 ui objects 的高度,但是 UI 文档对此有一些说明。

Old Fiddle

$(function() {
  $(".appointments").droppable({
    greedy: true,
    scope: "day",
    drop: function(event, ui) {
              console.log(event.target.getBoundingClientRect().top + window.scrollY);
        console.log(event.target.getBoundingClientRect().left + window.scrollX);
        console.log(Math.floor(ui.helper[0].getBoundingClientRect().top + window.scrollY  - event.target.getBoundingClientRect().top + window.scrollY) + "px !important" );
      var ap = ui.draggable;
      $(this).append(ap);
      ap.css({
        top: ap.offset.top + "px",
        left: "0px"
      });
    }
  });
  $(".appointments").click(function(e) {
    const x = e.offsetX;
    const y = e.offsetY;
    console.log(x + ' ' + y);
    newElement = $("<div>", {
      class: "appointment"
    }).css({
      top: y + "px",
      height: "10px",
      background: "blue",
      width: "100%"
    }).appendTo($(this));
    newElement.draggable({
      containment: $("#container"),
      scope: "day"
    });
    newElement.on("resizestop", function(event, ui) {
      event.stopPropagation();
    });
    newElement.resizable({
      handles: 'n,s',
      minHeight: 1
    });
    newElement.on("resize", function(event, ui) {
      event.stopPropagation();
    });
    newElement.on("click", function(event, ui) {
      event.stopPropagation();
    });
    newElement.on("contextmenu", function(e) {
      event.preventDefault();
      alert("clicked");
    });
  });
});
.day {

font-size: 14px;
display: inline-block;
background: white;
font-weight: bold;
border: 1px black solid;
text-align: center;
width:20%;
overflow:visible;

}


.week {
font-size:14px;
height:auto;
}


.appointments {

margin-top:10px;
height:108px;  /* 9 hour work day */
position:relative;
}

.dates {
     background: #555;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div id = "container">

<div class="week row">
  <div id="2020-01-02" class="day col-xl">
    <span class="calday">Thu, 2020-01-02 </span>
    <div class="appointments">
    </div>
  </div>
  <div id="2020-01-03" class="day col-xl">
    <span class="calday">Fri, 2020-01-03 </span>
    <div class="appointments">
    </div>
  </div>
  <div id="2020-01-04" class="day end col-xl">
    <span class="calday">Sat, 2020-01-04 </span>
    <div class="appointments">
    </div>
  </div>
</div>

<div class="week row">
  <div id="2020-01-02" class="day col-xl">
    <span class="calday">Thu, 2020-01-02 </span>
    <div class="appointments">
    </div>
  </div>
  <div id="2020-01-03" class="day col-xl">
    <span class="calday">Fri, 2020-01-03 </span>
    <div class="appointments">
    </div>
  </div>
  <div id="2020-01-04" class="day end col-xl">
    <span class="calday">Sat, 2020-01-04 </span>
    <div class="appointments">
    </div>
  </div>
</div>

考虑以下片段。

$(function() {
  $(".appointments").droppable({
    greedy: true,
    scope: "day",
    drop: function(event, ui) {
      // console.log(ui);
      var ap = ui.draggable;
      $(this).append(ap);
      ap.css({
        top: ap.offset.top + "px",
        left: "0px"
      });
    }
  });
  $(".appointments").click(function(e) {
    const x = e.offsetX;
    const y = e.offsetY;
    console.log(x + ' ' + y);
    newElement = $("<div>", {
      class: "appointment"
    }).css({
      top: y + "px",
      height: "10px"
    }).appendTo($(this));
    newElement.draggable({
      containment: $(".row"),
      scope: "day"
    });
    newElement.on("resizestop", function(event, ui) {
      event.stopPropagation();
    });
    newElement.resizable({
      handles: 'n,s',
      minHeight: 1
    });
    newElement.on("resize", function(event, ui) {
      event.stopPropagation();
    });
    newElement.on("click", function(event, ui) {
      event.stopPropagation();
    });
    newElement.on("contextmenu", function(e) {
      event.preventDefault();
      alert("clicked");
    });
  });
});
.day {
  font-size: 14px;
  display: inline-block;
  background: white;
  font-weight: bold;
  border: 1px black solid;
  text-align: center;
  width: 20%;
  overflow: visible;
}

.week {
  font-size: 14px;
  height: auto;
}

.appointments {
  margin-top: 10px;
  height: 108px;
  /* 9 hour work day */
  position: relative;
}

.appointment {
  position: absolute;
  left: "0px";
  background-color: blue;
  width: 100%;
  cursor: move;
}

.dates {
  background: #555;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="week row">
  <div id="2020-01-02" class="day col-xl">
    <span class="calday">Thu, 2020-01-02 </span>
    <div class="appointments">
    </div>
  </div>
  <div id="2020-01-03" class="day col-xl">
    <span class="calday">Fri, 2020-01-03 </span>
    <div class="appointments">
    </div>
  </div>
  <div id="2020-01-04" class="day end col-xl">
    <span class="calday">Sat, 2020-01-04 </span>
    <div class="appointments">
    </div>
  </div>
</div>

现在,当点击发生时,新元素被创建并可拖动,但包含行。因此用户可以在当天或同一周的另一天拖放它。使用 Offset,我们可以将约会附加到当天的新位置。这将允许事件重叠,如果您愿意,您可以调整 top 以适应同一天的其他项目。