'NestedTable with 2 Child Rows R shiny

Can anyone kindly help me I have the following code, I require 1 Parent table which then expand to child and further expand to another child.

My code is here:

library(shiny)
library(shinydashboard)
library(tidyverse)
library(DT)

ui <- fluidPage(fluidRow(DT::dataTableOutput(width = "100%", "table")))

server <- function(input, output) {
  
  output$table = DT::renderDataTable({
    # Sample data
    
    DATA <- data.table(Team = c(3,3, 4, 4, 39, 41, 43), 
                       Workdone = c(2,2, 1, 1, 1, 1), 
                       Q1 = c(0,0, 0, 0, 0, 0), 
                       Q2 = c(1, 1, 1, 1,1,1), 
                       Q3 = c(0,0, 0, 0, 0, 0), 
                       Name = c("A", "B", "C", "D", "E", "F"), 
                       Number = c(1, 1, 1, 1,1,1), 
                       q1 = c(0,0,0,0,0,0), 
                       q2 = c(100, 100, 100, 100, 100, 100),
                       q3 = c(0,0,0,0,0,0),
                       Data = c("2020","2021", "2011", "2021", "2011", "2015"), 
                       Type = c("Normal","Normal","Normal","Normal","Normal","Normal"), 
                       ID = c(0,0, 0, 0, 0, 0), 
                       ID2 = c("A", "B", "C", "D", "E", "F"), 
                       Channel = c(1, 1, 1, 1,1,1), 
                       Topic1 = c(0,0,0,0,0,0), 
                       Topic2 = c(100, 100, 100, 100, 100, 100),
                       Topic3 = c(0,0,0,0,0,0))
    
    DATA <- data.table(DATA)
    
    #breaking 2 child tables
    DATA2 <-DATA[,c(6:17)]
    
    DATA2 <- DATA2[,
                   list(cars=list(.SD)),
                   by = list(Name,Number,q1,q2,q3)]
    DATA2 <- cbind(' ' = '&#9658;', DATA2)
    
    # Turn data table into a nested data.table by mpg, cyl
    DATA <- DATA[,
                 list(cars=list(DATA2)),
                 by = list(Team, Workdone,Q1,Q2,Q3)]
    DATA <- cbind(' ' = '&#9658;', DATA)
    
    callback <-  DT::JS("table.column(1).nodes().to$().css({cursor: 'pointer'});",
                        "// Format the nested table into another table",
                        "var childId = function(d){",
                        "var tail = d.slice(2, d.length - 1);",
                        " return 'child_' + tail.join('_').replace(/[\\s|\\.|'|,|\\(|\\)]/g, '_');",
                        "};",
                        "var format = function (d) {",
                        "  if (d != null) {",
                        "    var id = childId(d);",
                        "    var html = ",
                        "          '<table class=\"display compact\" id=\"' + id + '\"><thead><tr>';",
                        "    for (var key in d[d.length-1][0]) {",
                        "      html += '<th>' + key + '</th>';",
                        "    }",
                        "    html += '</tr></thead></table>'",
                        "    return html;",
                        "  } else {",
                        "    return '';",
                        "  }",
                        "};",
                        "var rowCallback = function(row, dat, displayNum, index){",
                        "  if($(row).hasClass('odd')){",
                        "    for(var j=0; j<dat.length; j++){",
                        "      $('td:eq('+j+')', row).css('background-color', 'white');",
                        "    }",
                        "  } else {",
                        "    for(var j=0; j<dat.length; j++){",
                        "      $('td:eq('+j+')', row).css('background-color', 'white');",
                        "    }",
                        "  }",
                        "};",
                        "var headerCallback = function(thead, data, start, end, display){",
                        "  $('th', thead).css({",
                        "    'border-top': '2px black' ,",
                        "    'color': 'black' ,",
                        "    'background-color': '#ffffff'",
                        "  });",
                        "};",
                        "var format_datatable = function (d) {",
                        "  var dataset = [];",
                        "  var n = d.length - 1;",
                        "  for (var i = 0; i < d[n].length; i++) {",
                        "    var datarow = $.map(d[n][i], function (value, index) {",
                        "      return [value];",
                        "    });",
                        "    dataset.push(datarow);",
                        "  }",
                        "  var id = 'table#' + childId(d);",
                        "  var subtable = $(id).DataTable({",
                        "                     'data': dataset ,",
                        "                     'autoWidth': true ,",
                        "                     'deferRender': true ,",
                        "                     'info': false ,",
                        "                     'lengthChange': false ,",
                        "                     'ordering': d[n].length > 1 ,",
                        "                     'order': [] ,",
                        "                     'paging': false ,",
                        "                     'scrollX': false ,",
                        "                     'scrollY': false ,",
                        "                     'searching': false ,",
                        "                     'sortClasses': false ,",
                        "                     'rowCallback': rowCallback ,",
                        "                     'headerCallback': headerCallback ,",
                        "            'columnDefs': [",
                        "              {targets: 3, width: '50px'},",
                        "              {targets: 4, width: '50px'},",
                        "              {targets: 5, width: '50px'},",
                        "              {targets: 0, width: '100px'},",
                        "              {targets: 1, width: '75px'},",
                        "              {targets: 2, width: '60px'},",
                        "              {targets: 0, className: 'dt-right'}",
                        "             ]",
                        "                   });",
                        "};",
                        "table.on('click', 'td.details-control', function () {",
                        "  var td = $(this) ,",
                        "      row = table.row(td.closest('tr'));",
                        "  if (row.child.isShown()) {",
                        "    row.child.hide();",
                        "    td.html('&#9658;');",
                        "  } else {",
                        "    row.child(format(row.data())).show();",
                        "    td.html('&CircleMinus;');",
                        "    format_datatable(row.data());",
                        "  }",
                        "});"
    )
    
    datatable(
      #configure datatable. Hide row number and cars columns [0,4] and enable details control on plus sign column[1]
      #turn rows into child rows and remove from parent
      
      DATA,
      escape = TRUE,
      options = list(
        searching = FALSE,
        dom = 't',pageLength = 30,
        columnDefs = list((list(className = 'details-center', targets = c(2:7))),
                          list(orderable = FALSE, className = 'details-control', targets = 1)
                          
        )
      ),
      callback = DT::JS(callback)
    ) 
    
  },server = FALSE)
}

shinyApp (ui = ui, server = server)

parentchildchild



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source