Demo can be viewed here
https://codepen.io/Yu-Tub/pen/vEEQemo
HTML
<div class="container">
<div style="padding: 0 0 40px;">
<div id="schedule"></div>
</div>
</div>
CSS
body {
padding-top: 60px;
/* 60px to make the container go all the way to the bottom of the topbar */
}
#schedule .sc_bar_insert {
background-color: #ff678a;
}
#schedule .example2 {
background-color: #3eb698;
}
#schedule .example3 {
color: #2c0000;
font-weight: bold;
background-color: #c7ae50;
}
#schedule .sc_bar.sc_bar_photo .head,
#schedule .sc_bar.sc_bar_photo .text {
padding-left: 60px;
}
#schedule .sc_bar.sc_bar_photo .photo {
position: absolute;
left: 10px;
top: 10px;
width: 35px;
}
#schedule .sc_bar.sc_bar_photo .photo img {
max-width: 100%;
border-radius: 50px;
}
#current-time-line {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
height: 100%;
background-color: red;
z-index: 1000;
}
JS
$(function () {
function updateTimeLine() {
// Get current time
var now = new Date();
var hours = now.getHours();
var minutes = now.getMinutes();
// Test only
hours = hours - 1;
// Calculate position
var position = 120 * (hours + minutes / 60) - 581;
// Update or create line
var $timeline = $("#current-time-line");
if ($timeline.length === 0) {
$timeline = $('<div id="current-time-line"></div>');
$("#schedule").append($timeline);
}
$timeline.css("left", position + "px");
}
$("#logs").append('<table class="table">');
var isDraggable = false;
var isResizable = false;
var $sc = $("#schedule").timeSchedule({
startTime: "07:00", // schedule start time(HH:ii)
endTime: "17:00", // schedule end time(HH:ii)
widthTime: 30 * 10, // cell timestamp example 10 minutes
widthTimeX: 10,
timeLineY: 60, // height(px)
verticalScrollbar: 20, // scrollbar (px)
timeLineBorder: 2, // border(top and bottom)
bundleMoveWidth: 6, // width to move all schedules to the right of the clicked time line cell
dataWidth: 120,
rows: {
0: {
title: "Taro",
subtitle: "Developer",
schedule: [
{
start: "08:00",
end: "10:00",
text: "Meeting",
data: {
class: "example2",
image:
"https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/1.png",
},
},
{
start: "09:30",
end: "11:20",
text: "Interview(Aika)",
data: {
class: "example3",
image:
"https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/2.png",
},
},
{
start: "13:00",
end: "18:00",
text: "Go out",
data: {},
},
],
},
1: {
title: "Saito",
subtitle: "Management",
schedule: [
{
start: "08:00",
end: "10:00",
text: "Meeting",
data: {
class: "example2",
image:
"https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/1.png",
},
},
],
},
2: {
title: "Daisuke Kato",
subtitle: "Management",
schedule: [
{
start: "11:00",
end: "14:00",
text: "Go out",
data: {
image:
"https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/3.png",
},
},
],
},
},
onAppendSchedule: function (node, data) {
if (data.data.class) {
node.addClass(data.data.class);
}
if (data.data.image) {
var $img = $('<div class="photo"><img></div>');
$img.find("img").attr("src", data.data.image);
node.prepend($img);
node.addClass("sc_bar_photo");
}
},
});
updateTimeLine();
setInterval(updateTimeLine, 10000);
});
I am trying to add a current timeline indicator to jquery.schedule, how can I make the indicator be on the time line, so that when the timeline is scrolled, the timeline indicator moves with it?
I have tried putting it in the .sc_main and .sc_data classes but it still doesn't work as I expected.
Fixes required in your code:
Red line indicator needs to be inside container so that it never goes outside of the container.
You need to update the red line position using scroll offset, by adding scrollLeft
directly to the left position.
Here is a working version:
$(function() {
function updateTimeLine() {
var now = new Date();
var hours = now.getHours();
var minutes = now.getMinutes();
hours = hours - 1; // For testing only
var position = 120 * (hours + minutes / 60) - 581;
var $timeline = $("#current-time-line");
if ($timeline.length === 0) {
$timeline = $('<div id="current-time-line"></div>');
$(".sc_main_box").append($timeline); // Append inside scrollable content
$(".sc_main_box").css("position", "relative"); // Ensure proper context
$timeline.css({
position: "absolute",
top: 0,
bottom: 0,
width: "2px",
backgroundColor: "red",
zIndex: 1000,
pointerEvents: "none"
});
}
// Save raw position in a data attribute
$timeline.data("base-left", position);
// Adjust with current scroll
var scrollLeft = $(".sc_main_box").scrollLeft();
$timeline.css("left", (position - scrollLeft) + "px");
}
// Initialize the timeSchedule plugin
var $sc = $("#schedule").timeSchedule({
startTime: "07:00", // schedule start time (HH:ii)
endTime: "17:00", // schedule end time (HH:ii)
widthTime: 30 * 10, // cell timestamp example 10 minutes
widthTimeX: 10,
timeLineY: 60, // height (px)
verticalScrollbar: 20, // scrollbar (px)
timeLineBorder: 2, // border (top and bottom)
bundleMoveWidth: 6, // width to move all schedules to the right of the clicked time line cell
dataWidth: 120,
rows: {
0: {
title: "Taro",
subtitle: "Developer",
schedule: [{
start: "08:00",
end: "10:00",
text: "Meeting",
data: {
class: "example2",
image: "https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/1.png"
}
},
{
start: "09:30",
end: "11:20",
text: "Interview(Aika)",
data: {
class: "example3",
image: "https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/2.png"
}
},
{
start: "13:00",
end: "18:00",
text: "Go out",
data: {}
}
]
},
1: {
title: "Saito",
subtitle: "Management",
schedule: [{
start: "08:00",
end: "10:00",
text: "Meeting",
data: {
class: "example2",
image: "https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/1.png"
}
}]
},
2: {
title: "Daisuke Kato",
subtitle: "Management",
schedule: [{
start: "11:00",
end: "14:00",
text: "Go out",
data: {
image: "https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/demo/img/3.png"
}
}]
}
},
onAppendSchedule: function(node, data) {
if (data.data.class) {
node.addClass(data.data.class);
}
if (data.data.image) {
var $img = $('<div class="photo"><img></div>');
$img.find("img").attr("src", data.data.image);
node.prepend($img);
node.addClass("sc_bar_photo");
}
}
});
// Call updateTimeLine function once to initialize
updateTimeLine();
// Update the timeline indicator every 10 seconds
setInterval(updateTimeLine, 10000);
// Scroll event to keep the indicator in sync with scroll
$(".sc_main_box").on("scroll", function() {
var $timeline = $("#current-time-line");
if ($timeline.length > 0) {
var baseLeft = $timeline.data("base-left") || 0;
var scrollLeft = $(this).scrollLeft();
$timeline.css("left", (baseLeft - scrollLeft) + "px");
}
});
});
body {
padding-top: 60px;
/* 60px to make the container go all the way to the bottom of the topbar */
}
#schedule .sc_bar_insert {
background-color: #ff678a;
}
#schedule .example2 {
background-color: #3eb698;
}
#schedule .example3 {
color: #2c0000;
font-weight: bold;
background-color: #c7ae50;
}
#schedule .sc_bar.sc_bar_photo .head,
#schedule .sc_bar.sc_bar_photo .text {
padding-left: 60px;
}
#schedule .sc_bar.sc_bar_photo .photo {
position: absolute;
left: 10px;
top: 10px;
width: 35px;
}
#schedule .sc_bar.sc_bar_photo .photo img {
max-width: 100%;
border-radius: 50px;
}
#current-time-line {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
height: 100%;
background-color: red;
z-index: 1000;
pointer-events: none;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/dist/css/style.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.14.1/jquery-ui.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/ateliee/jquery.schedule@master/dist/js/jq.schedule.min.js"></script>
</head>
<body>
<div class="container">
<div style="padding: 0 0 40px;">
<div id="schedule"></div>
</div>
</div>
</body>
</html>