【问题标题】:DataTable rows.every function IssueDataTable rows.every 函数问题
【发布时间】:2021-05-06 19:19:24
【问题描述】:

我正在使用 jQuery DataTables 插件创建一个考勤跟踪器!我在功能/能力方面已经走得很远,并且已经被困了几个星期,试图弄清楚如何完成我想要它做的最后一部分。

我将在下面附上一个静态/可行的测试用例。所以我无法弄清楚的问题是如何根据子行单元格值设置父行的样式。 Sunday-Friday 列根据名为 SundayStatus、MondayStatus、TuesdayStatus 等的隐藏值进行着色。有两个值可能导致它变绿 (TW & P),两个值可能导致它变黄 (NR & O),还有两个值导致它变红 (PTO & H)。在我的rows.every(function ( rowIdx, tableLoop, rowLoop ) { 函数中,我需要找到一种方法来操作数据并根据每一天的出勤值向父行添加类。

P.S.(我创建了自己的插件 $.fn.dataTable.ext.search.push(function 来搜索表中的所有数据,并且只显示周日至周五的日期是本周日期的项目。

5/10 更新 Andrew 的答案更新在正确的轨道上,我对今天的格式做了一个小改动,并将 var result = Object.keys(data).find(key => data[key].substring(0,10) === today); 更改为 @ 987654325@。然后,我在我的动态代码中创建了一个条件,以读取反向查找的结果,并根据结果将行着色为某种颜色。

这是我之前在帖子中的 sn-p 中的静态示例的 JSFiddle:https://jsfiddle.net/BeerusDev/y8t0xoze/19/

在此更新中,我没有预见到的最后一个也是最后一个问题是,一切似乎都工作正常,但它从发布到 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);

【问题讨论】:

    标签: javascript jquery datatables


    【解决方案1】:

    这看起来非常接近,对我来说!

    以下是我建议的一些更改:

    1. 在结束&lt;/table&gt; 标记之后,还有一个额外的&lt;body&gt; 标记。这看起来不正确 - 它应该被删除。我认为这不会导致任何错误 - 但值得修复。

    2. 在您的 rows.every() 函数中,data 变量是一个普通数组 - 例如:

      [“IT”、“名称 1”、“这里的位置”、“05/02/2021”、“05/03/2021”、“P”、...]

    因此您不能使用data.MondayStatus - 因为那将是undefined。而是使用 data[5] 之类的东西来获取数组中的第 6 项 (P)。

    1. 如果您想更改某个位置(例如“IT”或“OM”)的行的背景颜色,可以使用如下选择器:

      $("tr[data-name='IT'] td").addClass("green");

    这是有效的,因为您已经将一个名为 data-name 的自定义属性添加到相关的 &lt;td&gt; 标记中。选择器使用该自定义属性找到&lt;td&gt; 标记,它是&lt;tr&gt; 标记的子标记。

    但是,这里的问题是:您正试图将类分配给一个表节点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"),您可以扩展此逻辑以处理不同的值和不同的类名(不仅仅是“绿色”),无论您需要什么整体逻辑。我的逻辑只是一个展示颜色变化的小演示。


    更新以处理“今天”

    为了展示该方法,我们假设以下记录:

    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();。我可能弄错了一些键(大写/小写) - 但如果是这种情况,您可以调整测试数据。

    现在,我得到今天的日期,其格式与 data 对象中的日期格式相同:

    var today = moment().format("YYYY-MM-DD"); // "2021-05-10"
    

    我使用该值在data 变量中查找等效值,并返回该条目的键名:

    var result = Object.keys(data).find(key => data[key].substring(0,10) === today); // "Monday"
    

    这基本上是您通常所做的反向查找。我们不是从键开始,而是从值开始并以键结束 - 在这种情况下,键是字符串“Friday”。

    现在我们获取这个字符串并将“状态”附加到它。

    这给了我们一个实际的密钥字符串:“FridayStatus”。

    现在我们使用该键来查找今天的状态(如果它完全存在于 data 对象中):

    var todayStatus = result ? data[result + 'Status'] : 'n/a'; // "P"
    

    如果日期不存在,那么您最终将获得“n/a”状态。

    总的来说,这为我们提供了一种快速获取当前状态的方法,而无需执行大量 if/else 逻辑。

    获得今天的状态后,您可以在较小的 if/else 中使用它来选择要应用于行的所需颜色。

    【讨论】:

    • 我使用 .MondayStatus 因为我的实际应用程序正在使用通过 ajax 调用接收的对象数据
    • 明白。在那种情况下,我的观点(2)是无关紧要的。而且我确定您已经相应地调整了第 (3) 点。
    • 查看我最近的编辑,我想我用rows.every(function 得到了它,现在我只需要通读数据行并且只根据 currDay 值更新顶部父行 =无论它可能是什么价值
    • 好的 - 所以,与其尝试编辑你的代码(并破坏某些东西),我提供了一些独立的代码,向你展示了一种方法(假设我理解你想要做什么) .如果该方法有帮助,您可以将其合并到您的 rows.every 处理中。
    • 谢谢!虽然当我尝试记录结果和今天的状态时,我在控制台中登录了这个:5/10/2021 undefined n/a
    猜你喜欢
    • 2019-12-19
    • 2012-02-12
    • 2011-12-18
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    • 2011-03-09
    • 2011-09-27
    相关资源
    最近更新 更多