我正在使用DataTables论坛中类似于此示例的shiny应用程序中为DataTables实现callback函数。 到目前为止我对阅读DT 文档 (第4.4节)的想法是,可能可以通过options的columnDefs参数应用相同的类sum ,如下所示,但如果我只知道放置JS参数的位置也是有意义的像链接一样手动完成类。
您可以删除所有columnDefs和callback参数以查看示例起点。
app.R
library(shiny) library(DT) ui <- fluidPage( title = 'Select Table Rows', hr(), h1('A Server-side Table'), fluidRow( column(9, DT::dataTableOutput('x3')) ) ) server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] output$x3 = DT::renderDataTable(DT::datatable(mtcars2, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), fixedHeader = TRUE, dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print') # columnDefs = JS("[ # { className: 'sum', 'targets': [ 1,2 ] } # ]") # ), #callback = JS( # " function(row, data, start, end, display) { # var api = this.api(); # # api.columns('.sum', { page: 'current' }).every(function () { # var sum = api # .cells( null, this.index(), { page: 'current'} ) # .render('display') # .reduce(function (a, b) { # var x = parseFloat(a) || 0; # var y = parseFloat(b) || 0; # return x + y; # }, 0); # console.log(this.index() +' '+ sum); //alert(sum); # $(this.footer()).html(sum); # }); #}" ) ) ) } shinyApp(ui = ui, server = server)最终解决方案
library(shiny) library(DT) ui <- fluidPage( title = 'Select Table Rows', hr(), h1('A Server-side Table'), fluidRow( column(9, DT::dataTableOutput('x3')) ) ) server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] sketch <- htmltools::withTags(table( class = "display", style = "bootstrap", tableHeader(colnames(mtcars2)), tableFooter(colnames(mtcars2)) )) output$x3 = DT::renderDataTable(DT::datatable(mtcars2, container = sketch, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print'), footerCallback = JS( "function( tfoot, data, start, end, display ) {", "var api = this.api(), data;", "total = api.column( 1, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total1 = api.column( 2, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total2 = api.column( 3, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total3 = api.column( 4, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total4 = api.column( 5, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total5 = api.column( 6, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total6 = api.column( 7, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total7 = api.column( 8, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "$( api.column( 1 ).footer() ).html(total.toFixed(2)); $( api.column( 2 ).footer() ).html(total1.toFixed(2)); $( api.column( 3 ).footer() ).html(total2.toFixed(2)); $( api.column( 4 ).footer() ).html(total3.toFixed(2)); $( api.column( 5 ).footer() ).html(total4.toFixed(2)); $( api.column( 6 ).footer() ).html(total5.toFixed(2)); $( api.column( 7 ).footer() ).html(total6.toFixed(2)); $( api.column( 8 ).footer() ).html(total7.toFixed(2));", "}" )) )) } shinyApp(ui = ui, server = server)我意识到这可能是JS的糟糕形式,但是,在我的情况下,这最有效,因此我可以对每个应用不同的选项(某些货币符号,某些平均值,不同的小数精度等)。
I'm working on implementing a callback function for DataTables in a shiny app similar to this example from the DataTables forum. My thought so far from reading the DT documentation (section 4.4) was that it might be possible to apply the same class sum through the columnDefs argument of options as below, but it would also make sense if I just knew where to put the JS argument to do the classes manually like in the link.
You can delete all the columnDefs and callback arguments to see an example starting point.
app.R
library(shiny) library(DT) ui <- fluidPage( title = 'Select Table Rows', hr(), h1('A Server-side Table'), fluidRow( column(9, DT::dataTableOutput('x3')) ) ) server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] output$x3 = DT::renderDataTable(DT::datatable(mtcars2, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), fixedHeader = TRUE, dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print') # columnDefs = JS("[ # { className: 'sum', 'targets': [ 1,2 ] } # ]") # ), #callback = JS( # " function(row, data, start, end, display) { # var api = this.api(); # # api.columns('.sum', { page: 'current' }).every(function () { # var sum = api # .cells( null, this.index(), { page: 'current'} ) # .render('display') # .reduce(function (a, b) { # var x = parseFloat(a) || 0; # var y = parseFloat(b) || 0; # return x + y; # }, 0); # console.log(this.index() +' '+ sum); //alert(sum); # $(this.footer()).html(sum); # }); #}" ) ) ) } shinyApp(ui = ui, server = server)Final solution:
library(shiny) library(DT) ui <- fluidPage( title = 'Select Table Rows', hr(), h1('A Server-side Table'), fluidRow( column(9, DT::dataTableOutput('x3')) ) ) server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] sketch <- htmltools::withTags(table( class = "display", style = "bootstrap", tableHeader(colnames(mtcars2)), tableFooter(colnames(mtcars2)) )) output$x3 = DT::renderDataTable(DT::datatable(mtcars2, container = sketch, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print'), footerCallback = JS( "function( tfoot, data, start, end, display ) {", "var api = this.api(), data;", "total = api.column( 1, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total1 = api.column( 2, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total2 = api.column( 3, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total3 = api.column( 4, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total4 = api.column( 5, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total5 = api.column( 6, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total6 = api.column( 7, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "total7 = api.column( 8, { page: 'current'} ).data().reduce( function ( a, b ) {return a + b;} )", "$( api.column( 1 ).footer() ).html(total.toFixed(2)); $( api.column( 2 ).footer() ).html(total1.toFixed(2)); $( api.column( 3 ).footer() ).html(total2.toFixed(2)); $( api.column( 4 ).footer() ).html(total3.toFixed(2)); $( api.column( 5 ).footer() ).html(total4.toFixed(2)); $( api.column( 6 ).footer() ).html(total5.toFixed(2)); $( api.column( 7 ).footer() ).html(total6.toFixed(2)); $( api.column( 8 ).footer() ).html(total7.toFixed(2));", "}" )) )) } shinyApp(ui = ui, server = server)I realize this is probably bad form for JS, however, in my case this works best so that I can apply different options to each (some currencies symbols, some averages, different decimal precisions etc.).
最满意答案
为了显示页脚中的总和/总数,您必须在表中添加一个容器,如下所示。 我还更改了JS代码:下面提供的版本必须正常工作。 不幸的是,我不知道你的JS代码有什么问题,因为我不是javascript的人。 您可以使用HTML(...)部分来更改总和的表示。
server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] sketch = htmltools::withTags(table(tableFooter(c("",0,0,0,0,0,0,0,0)))) output$x3 = DT::renderDataTable(DT::datatable(mtcars2, container = sketch, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), fixedHeader = TRUE, dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print') footerCallback = JS( "function( tfoot, data, start, end, display ) {", "var api = this.api();", "$( api.column( 1 ).footer() ).html(", "api.column( 1).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 2 ).footer() ).html(", "api.column( 2 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 3 ).footer() ).html(", "api.column( 3 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 4 ).footer() ).html(", "api.column( 4 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 5 ).footer() ).html(", "api.column( 5 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 6 ).footer() ).html(", "api.column( 6 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 7 ).footer() ).html(", "api.column( 7 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 8 ).footer() ).html(", "api.column( 8 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "}") ) ) ) }In order to show the sum/total in the footer, you have to add a container to your table as done below. I also changed the JS code: the version provided below must work. Unfortunately, I cannot tell what was wrong with your JS code as I am not the javascript guy. You can play with the HTML(...) part to change the presentation of your sums.
server <- function(input, output, session) { # server-side processing mtcars2 = mtcars[, 1:8] sketch = htmltools::withTags(table(tableFooter(c("",0,0,0,0,0,0,0,0)))) output$x3 = DT::renderDataTable(DT::datatable(mtcars2, container = sketch, extensions = 'Buttons', options = list( scrollX = TRUE, scrollY = TRUE, pageLength = 10, order = list(list(1, 'asc')), fixedHeader = TRUE, dom = 'Blrtip', buttons = c('copy', 'csv', 'excel', 'pdf', 'print') footerCallback = JS( "function( tfoot, data, start, end, display ) {", "var api = this.api();", "$( api.column( 1 ).footer() ).html(", "api.column( 1).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 2 ).footer() ).html(", "api.column( 2 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 3 ).footer() ).html(", "api.column( 3 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 4 ).footer() ).html(", "api.column( 4 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 5 ).footer() ).html(", "api.column( 5 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 6 ).footer() ).html(", "api.column( 6 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 7 ).footer() ).html(", "api.column( 7 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "$( api.column( 8 ).footer() ).html(", "api.column( 8 ).data().reduce( function ( a, b ) {", "return a + b;", "} )", ");", "}") ) ) ) }更多推荐
发布评论