Monday, 24 May 2021

Append JS Data to a Table Header (Update Header with that Item)

I have created a DataTable that is an attendance tracker and I have sort of changed the format of it in its entirety. Instead of having the status in the cells for each row (P, PTO, TRV, H, etc.), I had the Monday-Friday Dates and styled the rows based off of that attribute, and that became way too much to keep up with and my code readability was trash. I have found a better method to go about this. I am now inserting the Status under each day column header, and based off the day's status, it styles the Department row. If you want to find out the Location of the Employee of that day, all you do is hover over the day status and it brings up a tooltip with the location and Date of that day. Instead of having the date appear in the tooltip (I just want the Location), I have been trying to figure out how to append it to the <th> of #myTable.

I came across https://datatables.net/reference/option/columns.title but this seems to only be updated by Static Data.

Here is my working example (minus the header update):

var jsonOBJ = [{
  "Department": "IT",
  "Employee": "Beerus Dev",
  "Monday": "05/17/2021",
  "MondayStatus": "P",
  "MondayLocation": "Office",
  "Tuesday": "05/18/2021",
  "TuesdayStatus": "P",
  "TuesdayLocation": "Office",
  "Wednesday": "05/19/2021",
  "WednesdayStatus": "P",
  "WednesdayLocation": "Office",
  "Thursday": "05/20/2021",
  "ThursdayStatus": "P",
  "ThursdayLocation": "Office",
  "Friday": "05/21/2021",
  "FridayStatus": "P",
  "FridayLocation": "Office"
}]

$(document).ready(function() {
    moment.suppressDeprecationWarnings = true;
    
    $.fn.dataTable.ext.search.push(
    function( settings, searchData, index, rowData, counter ) {
        var now = moment();
        var monday = now.clone().weekday(1);
        var friday = now.clone().weekday(5);
        
        let mondayF = monday.format('MM/DD/YYYY');
        let fridayF = friday.format('MM/DD/YYYY');
        
        //console.log(sundayF); 
        //console.log(fridayF);
        
        var sMonday = searchData[2];
        var sFriday = searchData[10];
        
        if (mondayF == sMonday && fridayF == sFriday) {
            return true;
        }
        return false;
    }
);
        var collapsedGroups = {};
        var top = '';
        var parent = '';
    
        var table = $('#myTable').DataTable({
            data: jsonOBJ,
            "pageLength" : 50,
            "columns": [
                {"data": "Department",
              visible: false},
                { "data": "Employee"},
                { "data": "Monday", visible: false,
                render: function(data, type, row){
                if(type === "sort" || type === "type"){
                    return data;
                }
                return moment(data).format("MM/DD/YYYY");
            }
            },
                {"data": "MondayStatus"},
                { "data": "Tuesday", visible: false,
                render: function(data, type, row){
                if(type === "sort" || type === "type"){
                    return data;
                }
                return moment(data).format("MM/DD/YYYY");
            }
            },
                {"data": "TuesdayStatus"},
                { "data": "Wednesday", visible: false,
                render: function(data, type, row){
                if(type === "sort" || type === "type"){
                    return data;
                }
                return moment(data).format("MM/DD/YYYY");
            }
            },
                {"data": "WednesdayStatus"},
                { "data": "Thursday", visible: false,
                render: function(data, type, row){
                if(type === "sort" || type === "type"){
                    return data;
                }
                return moment(data).format("MM/DD/YYYY");
            }
            },
                {"data": "ThursdayStatus"},
                { "data": "Friday", visible: false,
                render: function(data, type, row){
                if(type === "sort" || type === "type"){
                    return data;
                }
                return moment(data).format("MM/DD/YYYY");
            }
            },
                {"data": "FridayStatus",}
            ],
            columnDefs: [
            { "targets": 3,
                "render": function (data, type, full, meta) {
            return type === 'display'? '<div title="Location: ' + full.MondayLocation + '\n' + "Date: " + moment(full.Monday).format("MM/DD/YYYY") + '">' + data : data;
                }     
            },
            { "targets": 5,
                "render": function (data, type, full, meta) {
            return type === 'display'? '<div title="Location: ' + full.TuesdayLocation + '\n' + "Date: " + moment(full.Tuesday).format("MM/DD/YYYY") +'">' + data : data;
                }     
            },
            { "targets": 7,
                "render": function (data, type, full, meta) {
            return type === 'display'? '<div title="Location: ' + full.WednesdayLocation + '\n' + "Date: " + moment(full.Wednesday).format("MM/DD/YYYY") +'">' + data : data;
                }     
            },
            { "targets": 9,
                "render": function (data, type, full, meta) {
            return type === 'display'? '<div title="Location: ' + full.ThursdayLocation + '\n' + "Date: " + moment(full.Thursda).format("MM/DD/YYYY") + '">' + data : data;
                }     
            },
            { "targets": 11,
                "render": function (data, type, full, meta) {
            return type === 'display'? '<div title="Location: ' + full.FridayLocation + '\n' + "Date: " + moment(full.Friday).format("MM/DD/YYYY") + '">' + data : data;
                }     
            }
            ] ,
            dom: "<'row'<'col-sm-12 col-md-10'f><'col-sm-12 col-md-2'B>>" +
                "<'row'<'col-sm-12'tr>>" +
                "<'row'<'col-sm-12 col-md-5'><'col-sm-12 col-md-7'>>",
            buttons: [{
                extend: 'collection',
                className: "btn-dark",
                text: 'Print Report',
                buttons: [{
                        extend: "excel",
                        className: "btn-dark"
                    },
                    {
                        extend: "print",
                        className: "btn-dark"
                    },
                ],
            }],
            order: [
                [0, 'asc']
            ],
            rowGroup: {
                dataSrc: [
                    'Department'
                ],
                startRender: function(rows, group, level, data) {
                    var all;
                    if (level === 0) {
                        top = group;
                        all = group;
                    } else if (level === 1) {
                        parent = top + group;
                        all = parent;
                        // if parent collapsed, nothing to do
                        if (!collapsedGroups[top]) {
                            return;
                        }
                    } else {
                        // if parent collapsed, nothing to do
                        if (!collapsedGroups[parent]) {
                            return;
                        }
                        all = top + parent + group;
                    }
    
                    var collapsed = !collapsedGroups[all];
                    //console.log('collapsed:', collapsed);
    
                    rows.nodes().each(function(r) {

                        r.style.display = collapsed ? 'none' : '';
                    });
                    //console.log('group:', group, level)
                 // loop all the rows in the group
                    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);

                        if(todayStatus === "P" || todayStatus === "TW") {
                            statusClass = 'green';
                        }
                        if(todayStatus === "NR" || todayStatus === "TRV") {
                            statusClass = 'yellow';
                        }
                        if (todayStatus === "PTO" || todayStatus === "H") {
                            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);
                }
    
            }
        });
    
        //loadData();
    
        $('#myTable tbody').on('click', 'tr.dtrg-start', function() {
            var name = $(this).data('name');
            collapsedGroups[name] = !collapsedGroups[name];
            table.draw(false);
        });
    });
h5{
text-align: center;
font-size: 40px;
}
.title {
    position: relative;
  background-color: lightgrey;
  color: #fff;
  border-radius: 0px;
  padding: 20px;
  font-size: 150%;
  border: 1px solid black;
}
p {
border-bottom:1px solid #B7DDF2;
color:#666666;
font-size:12px;
margin-bottom:20px;
padding-bottom:10px;
}
span {
color:#666666;
font-size:12px;
margin-bottom:1px;

}
.btn{
padding: 4px 12px;
margin-bottom: 0;
font-size: 14px;
line-height: 20px;
color: #333333;
text-align: center;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
vertical-align: middle;
cursor: pointer;
background-color: #f5f5f5;
border: 1px solid #B7DDF2;

}
.table th {
    text-align: center;
}
.table td{
    padding: 3px;
}
.dtrg-level-0::after {
 text-align: center;
}
.btn:hover{
color: #333333;
background-color: #e6e6e6;
}
th { font-size: 14px; }
td { font-size: 12px; text-align: center;}
div.container {
min-width: 980px;
margin: 0 auto;
}
.header {
padding: 10px;
text-align: center;
}

body {
font: 90%/1.45em "Helvetica Neue", HelveticaNeue, Verdana, Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
color: #333;
background-color: #fff;
}
div.dt-button-collection {
position: static;
}
table.dataTable tr.dtrg-group.green td {
background-color: #66b266 !important;
}
table.dataTable tr.dtrg-group.yellow td {
background-color: #ffff66 !important;
}
table.dataTable tr.dtrg-group.red td {
background-color: #ff6666 !important;
}
.green {
background-color: #66b266 !important;
}
.red {
background-color: #ff6666 !important;
}
.yellow {
background-color: #ffff66 !important;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <link rel ="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css"/>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <script src="https://momentjs.com/downloads/moment.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.flash.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.html5.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.print.min.js"></script>
    <script src="https://cdn.datatables.net/rowgroup/1.1.2/js/dataTables.rowGroup.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.6.3/js/buttons.bootstrap4.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
    <link rel ="stylesheet" href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.bootstrap4.min.css"/>
    <link rel ="stylsheet" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css"/>
    <link rel ="stylesheet" href="https://cdn.datatables.net/buttons/1.6.3/css/buttons.bootstrap4.min.css"/>
  </head>
  <h5><strong>Test Report</strong></h5>
  <div class ="container">
            <table id="myTable" class="table table-bordered" cellspacing="0" width="100%">
                <thead class="thead-dark">
                    <tr>
                    <th>Department</th>
                    <th>Employee</th>
                    <th>Monday Status</th>
                    <th>Monday</th>
                    <th>Tuesday Status</th>
                    <th>Tuesday</th>
                    <th>Wednesday Status</th>
                    <th>Wednesday</th>
                    <th>Thursday Status</th>
                    <th>Thursday</th>
                    <th>Friday Status</th>
                    <th>Friday</th>
                    </tr>
                </thead>
            </table>
            </div>
            <body>
</body>

</html>


from Append JS Data to a Table Header (Update Header with that Item)

No comments:

Post a Comment