Row Group Styling Issue

Row Group Styling Issue

zgoforthzgoforth Posts: 493Questions: 98Answers: 2

Hello,

So I thought that my row styling with statusColor was working fine. It appears whatever the most recent item added to the DataTable's status is, it styles the group row based off of the most recent item. So in my example, the current day is Wednesday, it is only going to read the day status for the Wednesday cells, which has 3 status which should be red (PTO & H), two status which should be green (P) and one status which should be yellow (NR). It is going to style the group row Green because that is the last/most recent object in the data set. In essence, it should style the group row "Red" because there are more "red" statuses than "green" or "yellow"

https://jsfiddle.net/BeerusDev/mznL52p8/47/

This question has accepted answers - jump to:

Answers

  • kthorngrenkthorngren Posts: 21,182Questions: 26Answers: 4,925

    The problem is your loop is setting the statusClass each time through the loop so the last one will be the one applied. In your loop you will need to count each status then once the loop is complete set the statusClass to the highest count.

    Here is some pseudo code:

    var counter = {red: 0, yellow: 0, green: 0};
    
    // inside the loop
    if(todayStatus === "P" || todayStatus === "TW") {
      counter.green++;
    }
    if(todayStatus....
    
    // After the loop determine which `counter` object is the greatest then set the `statusClass` based on that.
    

    Kevin

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2
    edited May 2021

    Updated test case: https://jsfiddle.net/BeerusDev/mznL52p8/57/

    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 => data[key] === today);
                        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);
                        var counter = {red: 0, yellow: 0, green: 0 };
                            if(todayStatus === "P" || todayStatus === "TW") {
                                counter.green++;
                            }
                            if(todayStatus === "NR" || todayStatus === "TRV") {
                                counter.yellow++;
                            }
                            if (todayStatus === "PTO" || todayStatus === "H") {
                                counter.red++;
                            }
                        console.log(counter);
                        if(counter.green > counter.red && counter.yellow){
                            statusClass = 'green';
                        }
                        if (counter.yellow > counter.green && counter.red){
                            statusClass = 'yellow';
                        }
                        if (counter.red > counter.green && counter.yellow){
                            statusClass = 'red';
                        }
    
                         });
                        //Add category name to the <tr>.
                            return $('<tr/>').addClass(statusClass)
                            .append('<td colspan="8" style="text-align: left;">' + group + ' (' + rows.count() + ')</td>')
                            .attr('data-name', all)
                            .toggleClass('collapsed', collapsed);
                    }
    

    I thought this would work, but it gives no errors and nothing the statusClass doesn't get added to the row.

  • kthorngrenkthorngren Posts: 21,182Questions: 26Answers: 4,925
    Answer ✓

    Line 19 should be initialized before the loop (before line 2). Otherwise you are resetting the values each time through the loop. The console.log(counter); in line 29 should show this is happening.

    The if statements aren't going to work, they need to look like this:

    if(counter.green > counter.red && counter.green > counter.yellow)
    

    Also the if statements lines 30-38 should come after the loop - between lines 40 and 41.

    Kevin

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    So I have encountered an unexpected error, which is good because it is very possible to be a case that could happen. So if I have a group where the child rows have 2 green todayStatus and 2 yellow todayStatus, it will even out and no class will be added to the group row, resulting in it staying grey.

    I have been suggested to use percentages instead, which I have never really worked with before in JS.

    I came up with part of a potential solution, after the counter++ if statements, could I do this?

    var countTot = counter.green + counter.yellow + counter.red;
    var greenTotPerc = (counter.green/countTot)*100;
    var yellowTotPerc = (counter.yellow/countTot)*100;
    var redTotPerc = (counter.red/countTot)*100;
    
    //This is where I am stuck to append the statusClass
    
    if( greenTotPerc >= .75 ){ statusClass = 'green'; }
    if(yellowTotPerc > .50 && yellowTotPerc < .75){ statusClass = 'yellow';}
    if(redTotPerc <= .50 ){statusClass = 'red';}
    
    
  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    On my actual implmentation, it does the styling but I do not think it is correct, then when I update my Fiddle to match the code, it console.logs() NaN. https://jsfiddle.net/BeerusDev/mznL52p8/63/

  • kthorngrenkthorngren Posts: 21,182Questions: 26Answers: 4,925
    Answer ✓

    it will even out and no class will be added to the group row, resulting in it staying grey.

    You can handle this with percentages (not sure what the result of your code snippet will be - you will need to test it) or you can put in conditions that will handle the ties and other cases or you can default statusClass to a color and if none of the conditions are met it will be the default color.

    The logic you choose is up to your specific requirements. The code to apply that logic is standard Javascript and outside of Datatables functionality. A better place for Javascript help is to search Stack Overflow for ideas of how to code what you want.

    Kevin

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    It seems to work at first, but it actually isn't. I just created a question on SO so hopefully someone can help me there.

    But here is the result of my proposed snippet https://jsfiddle.net/BeerusDev/mznL52p8/75/

  • zgoforthzgoforth Posts: 493Questions: 98Answers: 2

    IT appears as if I only include:

                         if( greenTotPerc >= 75 ){ statusClass = 'green'; } else if (greenTotPerc < 75 && greenTotPerc > 50) {statusClass = 'yellow';} else if(greenTotPerc <= 50) {statusClass = 'red';}
    
    

    it works, here is my test case: https://jsfiddle.net/BeerusDev/mznL52p8/82/

    UPDATE it doesn't work. If you see the HR dropdown you can tell

This discussion has been closed.