使用 JavaScript/jQuery 设置范围时间然后在移动到另一个时隙时更新
Setting a Ranged Time Then Updating When Moved to Another Time Slot Using JavaScript/jQuery
抱歉,如果我的标题有点含糊。我很难将我的问题表达为标题。
我想要做的是拥有一个动态创建 HTML table 的表单(简单)。我表单中的一个元素要求持续时间,例如下午 1 点到 2 点或下午 1.20 点到 1.56 点(仍然很容易)。
现在,我想创建一个允许我上下移动行的拖放元素。但是,当我这样做时,我希望时间相应地进行调整。
示例:我有三行。 ROW A 的时间范围设置为下午 2 点到下午 2.45。 ROW B 的时间范围设置为下午 2 点 45 分到下午 3 点 15 分。 ROW C 的时间范围是下午 3.15 到 3.30。
如果我将 ROW C 移动到 ROW A 之上,ROW C 的新时间应该是下午 2 点到 2 点 15 分。然后 ROW A 应该调整到下午 2.15 到下午 3 点。 B 行现在应该是下午 3 点到 3 点 30 分。
因为用户可以指定任何时间范围,所以我能想到的唯一逻辑是使用 2,400 数字系统列出所有 24 小时。例如。而不是下午 1 点,它将是 1,300。然后使用逻辑,我会将 1,300 转换为 1:00PM 以供用户查看。 501 将转换为 5:01AM。等等
肯定有更简洁的方法来执行此操作。有任何想法吗?谢谢!
我建议选择您的应用程序所需的最大精度(可以是分钟或秒或更精确的东西)并使用这些精度值表示您的所有数据。您可以以您选择的任何精度为单位为每一行指定持续时间。假设您不担心日期,您也可以以相同的精度表示开始时间,将前一天的午夜视为 0。因此,根据您的示例,如果您的精度为分钟,则为 2 p.m。 = 14(2 p.m。24 小时制)* 60(分钟/小时)= 840,您的总开始时间为 840。A 行持续时间为 45(分钟),B 为 30,C是 15 - 你的行看起来像 [45, 30, 15] 的数组。
现在要计算每一行的开始和结束时间,这只是常规算法:取上一行的结束时间(或总开始时间,如果是第一行)并将该行的持续时间添加到它得到结束时间。例如。 A 行从 840 开始到 885 结束(840 开始 + 45 持续时间)。 B 行从 885 开始到 915 结束。C 行从 915 开始到 930 结束。
要将这些数字转换回 HH:MM,除以 60 并截断以获得 HH(在 24 小时内;您必须对 a.m 进行一些计算。/p.m.) 然后取模 60 得到分钟。例如。 915的C行开始时间为
Math.floor(915 / 60) // => 15 (that's 15 hours, so 3 p.m.)
915 % 60 // => 15 (15 minutes)
将它们放在一起,您将得到 15:15 的 24 小时制,或 3:15 p.m。正如预期的那样,这是您最初写的开始时间C 行
如果 C 行移到前面,它现在从 840(总开始时间)开始到 855(840 + 15 分钟持续时间)结束,A 行从 855 开始到 900 结束,B 行开始在 900 到 930 结束。
如果您确实需要担心日期,您可能需要考虑使用纪元以来的时间来控制您的整体起点,并从那里开始。
花了这么长时间,我头疼 - 服用 2 片 Excedrin 后上床睡觉,然后起床决定我要这样做。
希望可以,
var rows = [
{id : "1", start:1, end:4, content : "1", dur : 3},
{id : "2", start:4, end:7, content : "2", dur : 3},
{id : "3", start:7, end:11, content : "3", dur : 4},
{id : "4", start:11, end:15, content : "4", dur : 4},
{id : "5", start:15, end:16, content : "5", dur : 1},
]
, startIndex , endIndex;
function buildTable(){
var i = 0, l = rows.length, container = $('#tableHolder tbody'), tmpHold;
container.html('');
for(i; i<l; i++){
container.append('<tr><td>From: '+ rows[i].start +' To:' + rows[i].end+ ' content : ' + rows[i].content + ' duration : ' + rows[i].dur +'</td></tr>');
}
}
buildTable();
$( "#tableHolder tbody" ).sortable({
start: function( event, ui ) {
startIndex = Array.prototype.indexOf.call(ui.item[0].parentNode.childNodes, ui.item[0]);
},
stop: function( event, ui ) {
endIndex = Array.prototype.indexOf.call(ui.item[0].parentNode.childNodes, ui.item[0])
if(startIndex !== endIndex){
rebuildArray (startIndex, endIndex)
}
}
}).disableSelection();
function rebuildArray(startIndex,endIndex){
var tempVal, arrMiddle, arrStart, arrEnd, i, l, starTime;
tempVal = rows[startIndex];
arrMiddle = [tempVal];
rows.splice(startIndex,1);
arrStart = rows.slice(0,endIndex);
arrEnd = rows.slice(endIndex,rows.length+1);
rows = arrStart.concat(arrMiddle, arrEnd);
i = 0;
l = rows.length;
starTime = getEarlierStartTime();
for(i; i<l;i++){
starTime = updateMyTime(rows[i], starTime);
}
buildTable();
}
function getEarlierStartTime(){
var i, l, earliest;
i = 0;
l = rows.length;
for(i; i<l;i++){
if(!earliest) earliest = rows[i].start;
if(rows[i].start < earliest) earliest = rows[i].start;
}
return earliest;
}
function updateMyTime(row, startTime){
row.start = startTime;
row.end = startTime+row.dur;
return row.end;
}
应该是工作示例:http://jsfiddle.net/xgv0rc68/6/ - 没有测试太多。
它的作用是,无论您将行放置在何处,它都会选择该行的开始时间,如果然后将放置的行的持续时间添加到该开始时间,并将其用作下一行的开始时间,然后添加到下一行的开始时间它的持续时间....等等并重新构建整个table。
抱歉,如果我的标题有点含糊。我很难将我的问题表达为标题。
我想要做的是拥有一个动态创建 HTML table 的表单(简单)。我表单中的一个元素要求持续时间,例如下午 1 点到 2 点或下午 1.20 点到 1.56 点(仍然很容易)。
现在,我想创建一个允许我上下移动行的拖放元素。但是,当我这样做时,我希望时间相应地进行调整。
示例:我有三行。 ROW A 的时间范围设置为下午 2 点到下午 2.45。 ROW B 的时间范围设置为下午 2 点 45 分到下午 3 点 15 分。 ROW C 的时间范围是下午 3.15 到 3.30。
如果我将 ROW C 移动到 ROW A 之上,ROW C 的新时间应该是下午 2 点到 2 点 15 分。然后 ROW A 应该调整到下午 2.15 到下午 3 点。 B 行现在应该是下午 3 点到 3 点 30 分。
因为用户可以指定任何时间范围,所以我能想到的唯一逻辑是使用 2,400 数字系统列出所有 24 小时。例如。而不是下午 1 点,它将是 1,300。然后使用逻辑,我会将 1,300 转换为 1:00PM 以供用户查看。 501 将转换为 5:01AM。等等
肯定有更简洁的方法来执行此操作。有任何想法吗?谢谢!
我建议选择您的应用程序所需的最大精度(可以是分钟或秒或更精确的东西)并使用这些精度值表示您的所有数据。您可以以您选择的任何精度为单位为每一行指定持续时间。假设您不担心日期,您也可以以相同的精度表示开始时间,将前一天的午夜视为 0。因此,根据您的示例,如果您的精度为分钟,则为 2 p.m。 = 14(2 p.m。24 小时制)* 60(分钟/小时)= 840,您的总开始时间为 840。A 行持续时间为 45(分钟),B 为 30,C是 15 - 你的行看起来像 [45, 30, 15] 的数组。
现在要计算每一行的开始和结束时间,这只是常规算法:取上一行的结束时间(或总开始时间,如果是第一行)并将该行的持续时间添加到它得到结束时间。例如。 A 行从 840 开始到 885 结束(840 开始 + 45 持续时间)。 B 行从 885 开始到 915 结束。C 行从 915 开始到 930 结束。
要将这些数字转换回 HH:MM,除以 60 并截断以获得 HH(在 24 小时内;您必须对 a.m 进行一些计算。/p.m.) 然后取模 60 得到分钟。例如。 915的C行开始时间为
Math.floor(915 / 60) // => 15 (that's 15 hours, so 3 p.m.)
915 % 60 // => 15 (15 minutes)
将它们放在一起,您将得到 15:15 的 24 小时制,或 3:15 p.m。正如预期的那样,这是您最初写的开始时间C 行
如果 C 行移到前面,它现在从 840(总开始时间)开始到 855(840 + 15 分钟持续时间)结束,A 行从 855 开始到 900 结束,B 行开始在 900 到 930 结束。
如果您确实需要担心日期,您可能需要考虑使用纪元以来的时间来控制您的整体起点,并从那里开始。
花了这么长时间,我头疼 - 服用 2 片 Excedrin 后上床睡觉,然后起床决定我要这样做。
希望可以,
var rows = [
{id : "1", start:1, end:4, content : "1", dur : 3},
{id : "2", start:4, end:7, content : "2", dur : 3},
{id : "3", start:7, end:11, content : "3", dur : 4},
{id : "4", start:11, end:15, content : "4", dur : 4},
{id : "5", start:15, end:16, content : "5", dur : 1},
]
, startIndex , endIndex;
function buildTable(){
var i = 0, l = rows.length, container = $('#tableHolder tbody'), tmpHold;
container.html('');
for(i; i<l; i++){
container.append('<tr><td>From: '+ rows[i].start +' To:' + rows[i].end+ ' content : ' + rows[i].content + ' duration : ' + rows[i].dur +'</td></tr>');
}
}
buildTable();
$( "#tableHolder tbody" ).sortable({
start: function( event, ui ) {
startIndex = Array.prototype.indexOf.call(ui.item[0].parentNode.childNodes, ui.item[0]);
},
stop: function( event, ui ) {
endIndex = Array.prototype.indexOf.call(ui.item[0].parentNode.childNodes, ui.item[0])
if(startIndex !== endIndex){
rebuildArray (startIndex, endIndex)
}
}
}).disableSelection();
function rebuildArray(startIndex,endIndex){
var tempVal, arrMiddle, arrStart, arrEnd, i, l, starTime;
tempVal = rows[startIndex];
arrMiddle = [tempVal];
rows.splice(startIndex,1);
arrStart = rows.slice(0,endIndex);
arrEnd = rows.slice(endIndex,rows.length+1);
rows = arrStart.concat(arrMiddle, arrEnd);
i = 0;
l = rows.length;
starTime = getEarlierStartTime();
for(i; i<l;i++){
starTime = updateMyTime(rows[i], starTime);
}
buildTable();
}
function getEarlierStartTime(){
var i, l, earliest;
i = 0;
l = rows.length;
for(i; i<l;i++){
if(!earliest) earliest = rows[i].start;
if(rows[i].start < earliest) earliest = rows[i].start;
}
return earliest;
}
function updateMyTime(row, startTime){
row.start = startTime;
row.end = startTime+row.dur;
return row.end;
}
应该是工作示例:http://jsfiddle.net/xgv0rc68/6/ - 没有测试太多。
它的作用是,无论您将行放置在何处,它都会选择该行的开始时间,如果然后将放置的行的持续时间添加到该开始时间,并将其用作下一行的开始时间,然后添加到下一行的开始时间它的持续时间....等等并重新构建整个table。