Столбец скрытой дочерней таблицы в DT - PullRequest
0 голосов
/ 20 апреля 2020

В моем блестящем приложении есть вложенное DataTable. В моей дочерней таблице всего 9 столбцов. Я пытаюсь скрыть 9-й столбец (population), поскольку пользователю на самом деле не нужно его видеть, но мне нужен этот столбец для выполнения некоторых вычислений. Я пытался использовать {targets: 9, visable: false}, в обратном вызове JS, но, похоже, это не работает. Должен ли я относиться к этому по-другому, потому что дочерняя таблица - это, по сути, список деталей? Как правильно индексировать девятые столбцы дочерней таблицы?

Данные

Parent
structure(list(Market = c("ABILENE, TX", "AKRON, OH"), `SQAD CPP` = c(9, 
37), `SQAD CPM` = c(7, 7), `Override CPP` = c(0, 0), `Override CPM` = c(0, 
0)), .Names = c("Market", "SQAD CPP", "SQAD CPM", "Override CPP", 
"Override CPM"), row.names = c(NA, -2L), class = "data.frame")
       Market SQAD CPP SQAD CPM Override CPP Override CPM
1 ABILENE, TX        9        7            0            0
2   AKRON, OH       37        7            0            0

Child
structure(list(Market = c("ABILENE, TX", "AKRON, OH", "ABILENE, TX", 
"AKRON, OH", "ABILENE, TX", "AKRON, OH", "ABILENE, TX", "AKRON, OH", 
"ABILENE, TX", "AKRON, OH", "ABILENE, TX", "AKRON, OH", "ABILENE, TX", 
"AKRON, OH", "ABILENE, TX", "AKRON, OH", "ABILENE, TX", "AKRON, OH"
), Daypart = c("Weekend", "Weekend", "Morning Drive", "Morning Drive", 
"Mon-Sun Average", "Mon-Sun Average", "Mon-Fri Average", "Mon-Fri Average", 
"Evening", "Evening", "Daytime", "Daytime", "Afternoon Drive", 
"Afternoon Drive", " Streaming/Digital Audio", " Streaming/Digital Audio", 
" Podcast", " Podcast"), `Mix (%)` = c(15, 15, 10, 10, 10, 10, 
5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10), `Spot:60 (%)` = c(6, 
6, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4), `Spot:30 (%)` = c(9, 
9, 6, 6, 6, 6, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6), `SQAD CPP` = c(24, 
73, 22, 146, 28, 107, 29, 118, 45, 84, 20, 118, 24, 135, 17, 
73, 28, 118), `SQAD CPM` = c(18, 13, 17, 26, 21, 19, 22, 21, 
34, 15, 15, 21, 18, 24, 13, 13, 21, 21), `Override CPP` = c(24, 
73, 22, 146, 28, 107, 29, 118, 45, 84, 20, 118, 24, 135, 17, 
73, 28, 118), `Override CPM` = c(18, 13, 17, 26, 21, 19, 22, 
21, 34, 15, 15, 21, 18, 24, 13, 13, 21, 21), population = c(131800, 
562300, 131800, 562300, 131800, 562300, 131800, 562300, 131800, 
562300, 131800, 562300, 131800, 562300, 131800, 562300, 131800, 
562300)), .Names = c("Market", "Daypart", "Mix (%)", "Spot:60 (%)", 
"Spot:30 (%)", "SQAD CPP", "SQAD CPM", "Override CPP", "Override CPM", 
"population"), class = "data.frame", row.names = c(NA, -18L))
# Bind the market level and mix breakout data together for the final table
market_mix_table <- reactive({
  # Take a dependency on input$goButton
  input$goButton

  isolate({
    markets <- market_costings_gross_net()
    mix_breakout <- mix_breakout_digital_elements()
    # Make the dataframe
    # This must be met length(children) == nrow(dat)
    Dat <- NestedData(
      dat = markets,
      children = split(mix_breakout, mix_breakout$Market)
    )
    return(Dat)
  })
})
# Render the table
output$daypartTable <- DT::renderDataTable({
  # # Take a dependency on input$goButton
  # input$goButton
  # 
  # isolate({
    Server = FALSE
    # Whether to show row names (set TRUE or FALSE)
    rowNames <- FALSE
    colIdx <- as.integer(rowNames)
    # The data
    Dat <- market_mix_table()
    parentRows <- which(Dat[,1] != "")
    callback_js = JS(
      "function onUpdate(updatedCell, updatedRow, oldValue) {};",
      sprintf("var parentRows = [%s];", toString(parentRows-1)),
      sprintf("var j0 = %d;", colIdx),
      "var nrows = table.rows().count();",
      "for(var i=0; i < nrows; ++i){",
      "  if(parentRows.indexOf(i) > -1){",
      "    table.cell(i,j0).nodes().to$().css({cursor: 'pointer'});",
      "  }else{",
      "    table.cell(i,j0).nodes().to$().removeClass('details-control');",
      "  }",
      "}",
      "",
      "// make the table header of the nested table",
      "var format = function(d, childId){",
      "  if(d != null){",
      "    var html = ",
      "      '<table class=\"display compact hover\" ' + ",
      "      'style=\"padding-left: 30px;\" id=\"' + childId + '\"><thead><tr>';",
      "    for(var key in d[d.length-1][0]){",
      "      html += '<th>' + key + '</th>';",
      "    }",
      "    html += '</tr></thead><tfoot><tr>'",
      "    for(var key in d[d.length-1][0]){",
      "      html += '<th></th>';",
      "    }",
      "    return html + '</tr></tfoot></table>';",
      "  } else {",
      "    return '';",
      "  }",
      "};",
      "",
      "// row callback to style the rows of the child tables",
      "var rowCallback = function(row, dat, displayNum, index){",
      "  if($(row).hasClass('odd')){",
      "    $(row).css('background-color', 'white');",
      "    $(row).hover(function(){",
      "      $(this).css('background-color', 'lightgreen');",
      "    }, function() {",
      "      $(this).css('background-color', 'white');",
      "    });",
      "  } else {",
      "    $(row).css('background-color', 'white');",
      "    $(row).hover(function(){",
      "      $(this).css('background-color', 'lightblue');",
      "    }, function() {",
      "      $(this).css('background-color', 'white');",
      "    });",
      "  }",
      "};",
      "",
      "// header callback to style the header of the child tables",
      "var headerCallback = function(thead, data, start, end, display){",
      "  $('th', thead).css({",
      "    'color': 'black',",
      "    'background-color': 'white'",
      "  });",
      "};",
      "",
      "// make the datatable",
      "var format_datatable = function(d, childId, rowIdx){",
      "  // footer callback to display the totals",
      "  // and update the parent row",
      "  var footerCallback = function(tfoot, data, start, end, display){",
      "    $('th', tfoot).css('background-color', '#F5F2F2');",
      "    var api = this.api();",
      "// update the OVerride CPM when the Override CPP is changed",
      # "    var col_override_cpp = api.column(7).data();",
      # "    var",
      # "    for(var i = 0; i < col_override_cpp.length; i++){",
      # "      api.cell(i,3).data(parseInt(col_mix[i])*slider/100);",
      # "      api.cell(i,4).data(parseInt(col_mix[i])*slider2/100);",
      # "    }",
      "    api.columns().eq(0).each(function(index){",
      "      if(index == 0) return $(api.column(index).footer()).html('Mix Total');",
      "      var coldata = api.column(index).data();",
      "      var total = coldata",
      "          .reduce(function(a, b){return parseInt(a) + parseInt(b)}, 0);",
      "      if(index == 3 || index == 4 ||index == 5 || index == 6 || index==7 || index==8) {",
      "        $(api.column(index).footer()).html('');",
      "      } else {",
      "        $(api.column(index).footer()).html(total);",
      "      }",
      "      if(total == 100) {",
      "        $(api.column(index).footer()).css({'color': 'green'});",
      "      } else {",
      "        $(api.column(index).footer()).css({'color': 'red'});",
      "      }",
      "    })",
      "  // update the parent row",
      "    var col_share = api.column(2).data();",
      "    var col_CPP = api.column(5).data();",
      "    var col_CPM = api.column(6).data();",
      "    var col_Historical_CPP = api.column(7).data();",
      "    var col_Historical_CPM = api.column(8).data();",
      "    var CPP = 0, CPM = 0, Historical_CPP = 0, Historical_CPM = 0;",
      "    for(var i = 0; i < col_share.length; i++){",
      "      CPP += (parseInt(col_share[i])*parseInt(col_CPP[i]).toFixed(0));",
      "      CPM += (parseInt(col_share[i])*parseInt(col_CPM[i]).toFixed(0));",
      "      Historical_CPP += (parseInt(col_share[i])*parseInt(col_Historical_CPP[i]).toFixed(0));",
      "      Historical_CPM += (parseInt(col_share[i])*parseInt(col_Historical_CPM[i]).toFixed(0));",
      "    }",
      "    table.cell(rowIdx, j0+2).data((CPP/100).toFixed(2));",
      "    table.cell(rowIdx, j0+3).data((CPM/100).toFixed(2));",
      "    table.cell(rowIdx, j0+4).data((Historical_CPP/100).toFixed(2));",
      "    table.cell(rowIdx, j0+5).data((Historical_CPM/100).toFixed(2));",
      "  }",
      "  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;",
      "  if (Object.keys(d[n][0]).indexOf('_details') === -1) {",
      "    var subtable = $(id).DataTable({",
      "                 'data': dataset,",
      "                 'autoWidth': true,",
      "                 'deferRender': true,",
      "                 'info': false,",
      "                 'lengthChange': false,",
      "                 'ordering': d[n].length > 1,",
      "                 'order': [],",
      "                 'paging': true,",
      "                 'scrollX': false,",
      "                 'scrollY': false,",
      "                 'searching': false,",
      "                 'sortClasses': false,",
      "                 'pageLength': 50,",
      "                 'rowCallback': rowCallback,",
      "                 'headerCallback': headerCallback,",
      "                 'footerCallback': footerCallback,",
      "                 'columnDefs': [",
      "                  {targets: 8, visible: false},",
      "                  {targets: '_all', className: 'dt-center'}",
      "                 ]",
      "               });",
      "  } else {",
      "    var subtable = $(id).DataTable({",
      "            'data': dataset,",
      "            'autoWidth': true,",
      "            'deferRender': true,",
      "            'info': false,",
      "            'lengthChange': false,",
      "            'ordering': d[n].length > 1,",
      "            'order': [],",
      "            'paging': true,",
      "            'scrollX': false,",
      "            'scrollY': false,",
      "            'searching': false,",
      "            'sortClasses': false,",
      "            'pageLength': 50,",
      "            'rowCallback': rowCallback,",
      "            'headerCallback': headerCallback,",
      "            'footerCallback': footerCallback,",
      "            'columnDefs': [",
      "              {targets: 8, visible: false},",
      "              {targets: -1, visible: false},",
      "              {targets: 0, orderable: false, className: 'details-control'},",
      "              {targets: '_all', className: 'dt-center'}",
      "             ]",
      "          }).column(0).nodes().to$().css({cursor: 'pointer'});",
      "  }",
      "  subtable.MakeCellsEditable({",
      "    onUpdate: onUpdate,",
      "    inputCss: 'my-input-class',",
      "    columns: [7],",
      "    confirmationButton: {",
      "      confirmCss: 'my-confirm-class',",
      "      cancelCss: 'my-cancel-class'",
      "    }",
      "  });",
      "};",
      "",
      "// display the child table on click",
      "var children = [];", # array to store the id's of the already created child tables
      "table.on('click', 'td.details-control', function(){",
      "  var tbl = $(this).closest('table'),",
      "      tblId = tbl.attr('id'),",
      "      td = $(this),",
      "      row = $(tbl).DataTable().row(td.closest('tr')),",
      "      rowIdx = row.index();",
      "  if(row.child.isShown()){",
      "    row.child.hide();",
      "    td.html('&oplus;');",
      "  } else {",
      "    var childId = tblId + '-child-' + rowIdx;",
      "    if(children.indexOf(childId) === -1){", # this child table has not been created yet
      "      children.push(childId);",
      "      row.child(format(row.data(), childId)).show();",
      "      td.html('&CircleMinus;');",
      "      format_datatable(row.data(), childId, rowIdx);",
      "    }else{",
      "      row.child(true);",
      "      td.html('&CircleMinus;');",
      "    }",
      "  }",
      "});"
    )
    # Table
    table <- DT::datatable(
      Dat,
      callback = callback_js,
      rownames = rowNames,
      escape = -colIdx-1,
      style = "bootstrap4",
      extensions = 'Buttons',
        options = list(
          lengthMenu = list(c(-1, 10, 20),
                            c("All", 10, 20)),
          columnDefs = list(
            list(width = '30px'),
            list(width = '545px', targets = 1),
            # list(visible=FALSE, targets=8), # If I do this than the table doesn't render
            list(visible = FALSE, targets = ncol(Dat)-1+colIdx),
            list(orderable = FALSE, className = 'details-control', targets = colIdx),
            list(className = "dt-center", targets = "_all")
        )
      )
    )
    # Call the html tools deps (js & css files in this directory)
    dep <- htmltools::htmlDependency(
      "CellEdit", "1.0.19", src = 'www/',
      script = "dataTables.cellEdit.js", stylesheet = "dataTables.cellEdit.css")
    table$dependencies <- c(table$dependencies, list(dep))

    table %>% formatStyle(
      c('Market', 'SQAD CPP', 'SQAD CPM', 'Override CPP', 'Override CPM'),
      target = 'row',
      backgroundColor = "#F5F2F2"
    )
  # })
})
...