简体   繁体   中英

R Shiny - Child row in datatable (row data not rendering)

I'm following the example from this page: Expanding and collapsing child rows in Shiny DataTable to render a datatable in shiny that contains child rows. I've been able to adjust the code to fit my data set but I haven't been able to render the nested child rows [contained in nested column y , of data_today ]. So far, I've only been successful in rendering the column names. Any assistance is appreciated as I have zero experience writing javascript and can't figure out why the nested rows don't render.

# call back
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', 'papayawhip');",
                "    }",
                "  } else {",
                "    for(var j=0; j<dat.length; j++){",
                "      $('td:eq('+j+')', row).css('background-color', 'lemonchiffon');",
                "    }",
                "  }",
                "};",
                "var headerCallback = function(thead, data, start, end, display){",
                "  $('th', thead).css({",
                "    'border-top': '3px solid indigo',", 
                "    'color': 'indigo',",
                "    'background-color': '#fadadd'",
                "  });",
                "};",
                "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': true,",
                "                     'sortClasses': false,",
                "                     'rowCallback': rowCallback,",
                "                     'headerCallback': headerCallback,",
                "                     'columnDefs': [{targets: '_all', className: 'dt-center'}]",
                "                   });",
                "};",
                "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('&oplus;');",
                "  } else {",
                "    row.child(format(row.data())).show();",
                "    td.html('&CircleMinus;');",
                "    format_datatable(row.data());",
                "  }",
                "});"
)

# data set
data_today <- structure(list(Player = "Anthony Davis", title = "Anthony Davis (rest) will sit out the Lakers' preseason finale on Friday.", 
                   news = "LeBron James will join him on the sidelines, after the pair looked terrific together during an easy win on Wednesday. Davis already tweaked his thumb this preseason, so his fantasy owners should be thrilled that he's sitting out this exhibition.", 
                   Date = structure(18186, class = "Date"), y = list(structure(list(
                     title = c("Anthony Davis (right thumb) suited up on Wednesday and had eight points, 10 rebounds, eight assists, two blocks and one steal in 28 minutes vs. the Warriors.", 
                               "Anthony Davis (thumb) will play in Wednesday's preseason game against the Warriors.", 
                               "Anthony Davis (right thumb) went through a full practice on Tuesday and hopes to be cleared for Wednesday's preseason game against the Warriors.", 
                               "Anthony Davis (right thumb) went through a full practice on Tuesday and hopes to be cleared for Wednesday's preseason game against the Warriors.", 
                               "Late Monday night the Lakers announced that Anthony Davis suffered a sprained right thumb during the team's game against the Nets Saturday in China.", 
                               "An MRI on Anthony Davis' right thumb came back clean.", 
                               "Anthony Davis is now expected to receive an MRI on his right thumb on Monday, instead of Sunday.", 
                               "According to Shams Charania of The Athletic, initial exams on Anthony Davis' right thumb showed no ligament damage, and AD is believed to be dealing with a Grade 1 sprain.", 
                               "Updating a previous item, Anthony Davis will have diagnostic tests on his sprained right thumb upon his return to Los Angeles.", 
                               "Anthony Davis sprained his right thumb in Saturday's preseason game vs. Brooklyn and did not return.", 
                               "Anthony Davis contributed 16 points, two rebounds, five assists, one steal, two blocks and one turnover across 25 minutes during Thursday's preseason loss to the Nets.", 
                               "Anthony Davis had a superb preseason debut, scoring 22 points (9-of-16 FGs, 4-of-6 FTs) with 10 rebounds, two assists and one steal in 18 minutes against the Warriors."
                     ), news = c("The player with the highest ADP in Yahoo leagues gave owners a scare when he dinged his thumb this preseason. It was a minor Grade-1 sprain, fortunately, and being cleared for an exhibition is all we need to trust that he's fine -- he looked great, despite the shooting line at 3-of-9 without any treys. He provides plug-and-play greatness alongside LeBron James, who should make life even easier for AD than it was in New Orleans.", 
                                 "He got in a full practice yesterday without experiencing a setback, so he'll be cleared for tonight's game and is obviously in no danger of missing the regular-season opener. As long as he's healthy, he'll be an extremely fun player to own this season.", 
                                 "Davis wore a wrap on his right thumb and said he felt fine after getting through Tuesday's practice, although we wouldn't be shocked to see him get held out of tomorrow's exhibition. He'll be good to go for opening night, though, and while Karl-Anthony Towns makes for a safer No. 1 overall selection; AD offers the most upside.", 
                                 "Davis wore a wrap on his right thumb and said he felt fine after getting through Tuesday's practice, although we wouldn't be shocked to see him get held out of tomorrow's exhibition. He'll be good to go for opening night, though, and while Karl-Anthony Towns makes for a safer No. 1 overall selection; AD offers the most upside.", 
                                 "The initial results, which were made public Monday afternoon, came back clean so Davis and the Lakers were able to breathe a sigh of relief. The perennial All-Star is considered to be day-to-day, and it's worth noting that he took some shots during pregame without any kind of wrap/protection on his injured thumb. The Lakers open their regular season a week from Tuesday against the Clippers.", 
                                 "The MRI was just confirmation after initial tests came back clean as well. This is a huge relief for both the Lakers and for fantasy owners, but we wouldn't be surprised if the franchise held him out for the rest of preseason to let his Grade 1 sprain properly heal. He will definitely sit out on Monday night against the Warriors according to Chris Haynes of Yahoo Sports, and LeBron James (rest) will join him on the sidelines", 
                                 "The Lakers just returned from a long flight back from China, so they won't make their superstar report to their medical facilities. Initial exams reportedly showed no ligament damage, but we'll get official confirmation on that once the MRI results are announced. There's a decent chance AD will skip Monday's preseason game against the Warriors, but as of right now, this appears to be a fairly minor injury.", 
                                 "Per Charania, Davis will undergo an MRI on Sunday to confirm the diagnosis. The Lakers' next preseason contest is Monday vs. Golden State. LA then closes out its preseason schedule with two more games against the Warriors (Wednesday at home and Friday in Golden State). It's safe to assume the Lakers will rest AD this week, but as long as he is only dealing with a Grade 1 sprain, he should be good to go by opening night (Tuesday, Oct. 22). GM's who have already drafted Davis can breathe a sigh of relief.", 
                                 "Davis sprained his thumb in the first quarter of Saturday's preseason loss to the Nets while going for a block. After heading to the locker room, AD returned to the bench with his thumb wrapped in ice and was ruled out of the contest. Unfortunately, there is no X-ray machine at the Shenzhen arena where the game was played, thus the delay in getting test results. The Lakers play the Warriors on Monday at Staples Center, so we should have an update on his status shortly.", 
                                 "It appeared AD injured the thumb going up to block a shot at the rim early in the first quarter. He returned to the bench later in the first quarter with an ice pack wrapped around his thumb. It's just a meaningless preseason contest, so the Lakers obviously were going to err on the side of caution. Hopefully, it's just a minor issue. We'll stay tuned for an update. The Lakers' next preseason contest is Monday vs. Golden State.", 
                                 "AD is going to be a monster in his age-26 season, and with the Lakers' frontcourt being rather thin, he may not have the luxury of seeing many load management games this season. If Davis didn't have a history of health concerns, he'd be unanimously viewed as the clear-cut No. 1 option on draft day, but him playing for a competitive team should give him some extra incentive to play through pain. LeBron James finished with 20 points, six rebounds, two assists, two triples and one turnover in 25 minutes.", 
                                 "Davis manhandled the shorthanded Warriors frontcourt on Saturday and only needed the first half to do so. The Lakers have talked about funneling the offense through AD this season, and they got off to a good start with that here. He took six more shots than the next closest starter (LeBron with 10). AD is primed for another monster fantasy season."
                     ), Date = structure(c(18186, 18185, 18184, 18184, 18184, 
                                           18183, 18182, 18181, 18181, 18181, 18179, 18174), class = "Date"), 
                     Time = c("1:17 AM", "2:55 PM", "5:34 PM", "5:34 PM", 
                              "12:55 AM", "2:51 PM", "3:51 PM", "1:56 PM", "12:11 PM", 
                              "9:28 AM", "12:23 PM", "10:31 PM")), class = "data.frame", row.names = c(NA, 
                                                                                                       -12L)))), class = "data.frame", row.names = c(NA, -1L))

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

shinyApp(
  ui = fluidPage(
    DT::dataTableOutput('tbl')
  ),

  server = function(input, output) {
    output$tbl = DT::renderDataTable(
      datatable({
        cbind(' ' = '&oplus;', data_today)},
        escape = -2,
        options = list(
          columnDefs = list(
            list(visible = FALSE, targets = c(0,6)),
            list(orderable = FALSE, className = 'details-control', targets = 1)
          )
        ),
        callback = JS(callback)
      )
    )
  }
)

I think that quotes, commas and parentheses should be avoided in an id. So use this line:

"  return 'child_' + tail.join('_').replace(/[\\s|\\.|'|,|\\(|\\)]/g, '_');"

instead of

"  return 'child_' + tail.join('_').replace(/[\\s|\\.]/g, '_');"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM