DataTable rows.every 函数问题
DataTable rows.every function Issue
我正在使用 jQuery DataTables 插件创建出勤跟踪器!我对 functionality/capability 的了解已经很深了,并且已经被困了数周,试图弄清楚如何完成我希望它完成的最后一部分。
我将在下面附上一个 static/workable 测试用例。所以我无法弄清楚的问题是如何根据子行单元格值设置父行的样式。 Sunday-Friday 列根据名为 SundayStatus、MondayStatus、TuesdayStatus 等的隐藏值进行着色。有两个值可以使它变绿(TW 和 P),两个值可以使它变黄(NR 和 O),还有两个值可以使它变红(PTO 和 H)。在我的 rows.every(function ( rowIdx, tableLoop, rowLoop ) {
函数中,我需要找到一种方法来操作数据并根据每天的出勤值将 classes 添加到父行。
P.S。(我创建了自己的插件 $.fn.dataTable.ext.search.push(function
来搜索 table 中的所有数据,并且仅显示日期为周日至周五的项目在本周。
UPDATE 5/10 Andrew 在更新他的答案时走在了正确的轨道上,我对今天的格式做了一个小改动, 并将 var result = Object.keys(data).find(key => data[key].substring(0,10) === today);
更改为 var result = Object.keys(data).find(key => typeof data[key] === 'string' && data[key].startsWith(today));
。然后,我在我的动态代码中创建了一个条件,以读取反向查找的结果,并根据结果为该行着色。
这是我之前在 post 中的一个片段中的静态示例的 JSFiddle:https://jsfiddle.net/BeerusDev/y8t0xoze/19/
在这次更新中,我要处理的最后一个也是最后一个我没有预见到的问题是,一切似乎都运行良好,但它附加了第一个项目的状态 class post编辑到 DataTable 并且不考虑其他项目。我在试图找出解决此问题的方法时遇到了心理障碍,但这是我的动态应用程序中的 rows.every 函数,它位于我的 startRender 函数
中
var statusClass = '';
rows.every(function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
var node = this.node();
var today = moment().format("YYYY-MM-DD"); // "05/10/2021"
console.log(today);
//console.log(JSON.stringify(data));
var result = Object.keys(data).find(key => typeof data[key] === 'string' && data[key].startsWith(today)); // "Monday"
console.log(result);
var todayStatus = result ? data[result + 'Status'] : 'n/a';
console.log(todayStatus);
if(todayStatus === "P" || todayStatus === "TW") {
statusClass = 'green';
}
if(todayStatus === "NR" || todayStatus === "O") {
statusClass = 'yellow';
}
if (todayStatus === "PTO" || todayStatus === "H") {
statusClass = 'red';
}
});
//Add category name to the <tr>.
return $('<tr/>').addClass(statusClass)
.append('<td colspan="8">' + group + ' (' + rows.count() + ')</td>')
.attr('data-name', all)
.toggleClass('collapsed', collapsed);
这对我来说非常接近!
以下是我推荐的一些更改:
结束 </table>
标签后,还有一个额外的 <body>
标签。这看起来不正确 - 它应该被删除。我认为这不会导致任何错误 - 但值得修复。
在您的 rows.every()
函数中,data
变量是一个普通数组 - 例如:
[“IT”、“姓名 1”、“此处位置”、“05/02/2021”、“05/03/2021”、“P”、...]
因此您不能使用 data.MondayStatus
- 因为那将是 undefined
。而是使用 data[5]
之类的东西来获取数组中的第 6 项 (P
).
如果您想更改某个位置(例如“IT”或“OM”)的行的背景颜色,您可以使用这样的选择器:
$("tr[数据名称='IT'] td").addClass("绿色");
之所以有效,是因为您已经将名为 data-name
的自定义属性添加到相关的 <td>
标记中。选择器找到 <td>
标签,它是使用该自定义属性的 <tr>
标签的子标签。
但是,这里的问题是:您正在尝试将 class 分配给 table 节点 ,然后 DataTable 已完成构建。
要解决此问题,您可以将所有行循环逻辑移至 initComplete
函数:
initComplete: function(settings, json) {
this.api().rows().every(function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
var node = this.node().previousSibling; // to handle your row grouping
if (node !== null) {
if (data[5] === "P") {
var selectorVar = "[data-name='" + data[0] + "'] td";
$( selectorVar ).addClass("green");
}
}
});
}
而不是 if (data[5] === "P")
,您可以扩展此逻辑以处理不同的值和不同的 class 名称(不仅仅是“绿色”),无论您需要什么整体逻辑。我的逻辑只是一个展示颜色变化的小demo。
更新以处理“今天”
为了展示该方法,我们假设以下记录:
var data = {
"Department": "IT",
"Name": "Name 1",
"Locations": "Locations Here",
"Sunday": "2021-05-09",
"Monday": "2021-05-10",
"MondayStatus": "P",
"Tuesday": "2021-05-11",
"TuesdayStatus": "Q",
"Wednesday": "2021-05-12",
"WednesdayStatus": "R",
"Thursday": "2021-05-13",
"ThursdayStatus": "S",
"Friday": "2021-05-14",
"FridayStatus": "T"
};
这个 data
变量就是我认为您在 rows.every
函数中处理的变量。所以,它相当于 var data = this.data();
。我可能弄错了一些键 (uppercase/lowercase) - 但如果是这种情况,您可以调整测试数据。
现在,我得到今天的日期,其格式与 data
对象中的日期格式相匹配:
var today = moment().format("YYYY-MM-DD"); // "2021-05-10"
我使用此值在 data
变量中查找等效值,并且我 return 该条目的键名:
var result = Object.keys(data).find(key => data[key].substring(0,10) === today); // "Monday"
这基本上是您通常所做的反向查找。我们不是以键开头,而是以值开头并以键结束 - 在本例中,键是字符串“Friday”。
现在我们获取此字符串并在其后附加“Status”。
这给了我们一个实际的关键字符串:“FridayStatus”。
现在我们使用该键查找今天的状态(如果它存在于 data
对象中):
var todayStatus = result ? data[result + 'Status'] : 'n/a'; // "P"
如果日期不存在,那么您最终的状态将是“n/a”。
总的来说,这为我们提供了一种快速获取今天状态的方法,而无需执行大量 if/else 逻辑。
获得今天的状态后,您可以在较小的 if/else 中使用它来选择要应用到该行的所需颜色。
我正在使用 jQuery DataTables 插件创建出勤跟踪器!我对 functionality/capability 的了解已经很深了,并且已经被困了数周,试图弄清楚如何完成我希望它完成的最后一部分。
我将在下面附上一个 static/workable 测试用例。所以我无法弄清楚的问题是如何根据子行单元格值设置父行的样式。 Sunday-Friday 列根据名为 SundayStatus、MondayStatus、TuesdayStatus 等的隐藏值进行着色。有两个值可以使它变绿(TW 和 P),两个值可以使它变黄(NR 和 O),还有两个值可以使它变红(PTO 和 H)。在我的 rows.every(function ( rowIdx, tableLoop, rowLoop ) {
函数中,我需要找到一种方法来操作数据并根据每天的出勤值将 classes 添加到父行。
P.S。(我创建了自己的插件 $.fn.dataTable.ext.search.push(function
来搜索 table 中的所有数据,并且仅显示日期为周日至周五的项目在本周。
UPDATE 5/10 Andrew 在更新他的答案时走在了正确的轨道上,我对今天的格式做了一个小改动, 并将 var result = Object.keys(data).find(key => data[key].substring(0,10) === today);
更改为 var result = Object.keys(data).find(key => typeof data[key] === 'string' && data[key].startsWith(today));
。然后,我在我的动态代码中创建了一个条件,以读取反向查找的结果,并根据结果为该行着色。
这是我之前在 post 中的一个片段中的静态示例的 JSFiddle:https://jsfiddle.net/BeerusDev/y8t0xoze/19/
在这次更新中,我要处理的最后一个也是最后一个我没有预见到的问题是,一切似乎都运行良好,但它附加了第一个项目的状态 class post编辑到 DataTable 并且不考虑其他项目。我在试图找出解决此问题的方法时遇到了心理障碍,但这是我的动态应用程序中的 rows.every 函数,它位于我的 startRender 函数
中var statusClass = '';
rows.every(function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
var node = this.node();
var today = moment().format("YYYY-MM-DD"); // "05/10/2021"
console.log(today);
//console.log(JSON.stringify(data));
var result = Object.keys(data).find(key => typeof data[key] === 'string' && data[key].startsWith(today)); // "Monday"
console.log(result);
var todayStatus = result ? data[result + 'Status'] : 'n/a';
console.log(todayStatus);
if(todayStatus === "P" || todayStatus === "TW") {
statusClass = 'green';
}
if(todayStatus === "NR" || todayStatus === "O") {
statusClass = 'yellow';
}
if (todayStatus === "PTO" || todayStatus === "H") {
statusClass = 'red';
}
});
//Add category name to the <tr>.
return $('<tr/>').addClass(statusClass)
.append('<td colspan="8">' + group + ' (' + rows.count() + ')</td>')
.attr('data-name', all)
.toggleClass('collapsed', collapsed);
这对我来说非常接近!
以下是我推荐的一些更改:
结束
</table>
标签后,还有一个额外的<body>
标签。这看起来不正确 - 它应该被删除。我认为这不会导致任何错误 - 但值得修复。在您的
rows.every()
函数中,data
变量是一个普通数组 - 例如:[“IT”、“姓名 1”、“此处位置”、“05/02/2021”、“05/03/2021”、“P”、...]
因此您不能使用 data.MondayStatus
- 因为那将是 undefined
。而是使用 data[5]
之类的东西来获取数组中的第 6 项 (P
).
如果您想更改某个位置(例如“IT”或“OM”)的行的背景颜色,您可以使用这样的选择器:
$("tr[数据名称='IT'] td").addClass("绿色");
之所以有效,是因为您已经将名为 data-name
的自定义属性添加到相关的 <td>
标记中。选择器找到 <td>
标签,它是使用该自定义属性的 <tr>
标签的子标签。
但是,这里的问题是:您正在尝试将 class 分配给 table 节点 ,然后 DataTable 已完成构建。
要解决此问题,您可以将所有行循环逻辑移至 initComplete
函数:
initComplete: function(settings, json) {
this.api().rows().every(function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
var node = this.node().previousSibling; // to handle your row grouping
if (node !== null) {
if (data[5] === "P") {
var selectorVar = "[data-name='" + data[0] + "'] td";
$( selectorVar ).addClass("green");
}
}
});
}
而不是 if (data[5] === "P")
,您可以扩展此逻辑以处理不同的值和不同的 class 名称(不仅仅是“绿色”),无论您需要什么整体逻辑。我的逻辑只是一个展示颜色变化的小demo。
更新以处理“今天”
为了展示该方法,我们假设以下记录:
var data = {
"Department": "IT",
"Name": "Name 1",
"Locations": "Locations Here",
"Sunday": "2021-05-09",
"Monday": "2021-05-10",
"MondayStatus": "P",
"Tuesday": "2021-05-11",
"TuesdayStatus": "Q",
"Wednesday": "2021-05-12",
"WednesdayStatus": "R",
"Thursday": "2021-05-13",
"ThursdayStatus": "S",
"Friday": "2021-05-14",
"FridayStatus": "T"
};
这个 data
变量就是我认为您在 rows.every
函数中处理的变量。所以,它相当于 var data = this.data();
。我可能弄错了一些键 (uppercase/lowercase) - 但如果是这种情况,您可以调整测试数据。
现在,我得到今天的日期,其格式与 data
对象中的日期格式相匹配:
var today = moment().format("YYYY-MM-DD"); // "2021-05-10"
我使用此值在 data
变量中查找等效值,并且我 return 该条目的键名:
var result = Object.keys(data).find(key => data[key].substring(0,10) === today); // "Monday"
这基本上是您通常所做的反向查找。我们不是以键开头,而是以值开头并以键结束 - 在本例中,键是字符串“Friday”。
现在我们获取此字符串并在其后附加“Status”。
这给了我们一个实际的关键字符串:“FridayStatus”。
现在我们使用该键查找今天的状态(如果它存在于 data
对象中):
var todayStatus = result ? data[result + 'Status'] : 'n/a'; // "P"
如果日期不存在,那么您最终的状态将是“n/a”。
总的来说,这为我们提供了一种快速获取今天状态的方法,而无需执行大量 if/else 逻辑。
获得今天的状态后,您可以在较小的 if/else 中使用它来选择要应用到该行的所需颜色。