glin/reactable

reactable footer total is doubled with paginateSubRows = TRUE and row is expanded

vneyman opened this issue · 1 comments

Total is doubled for each expanded row when paginateSubRows = TRUE. The below example will show a total of 956.2 vs 478.1.
Is there a way to keep the footer total accurate. Maybe there is a javascript trick?

data <- MASS::Cars93[18:47, ] %>%
select(Manufacturer, Model, Type, Sales = Price)

reactable(
data,
defaultExpanded = TRUE,
paginateSubRows = TRUE,
groupBy = "Manufacturer",
searchable = TRUE,
columns = list(
Manufacturer = colDef(footer = "Total"),
Sales = colDef(
aggregate = "sum",
format = colFormat(currency = "USD"),
footer = JS("function(column, state) {
let total = 0
state.sortedData.forEach(function(row) {
total += row[column.id]
})
return total.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
}")
)
),
defaultColDef = colDef(footerStyle = list(fontWeight = "bold"))
)

glin commented

There is a way to tell if a row is grouped, but it's not well documented or obvious to use. A row will have a _subRows array property if it's grouped. You can ignore these rows, e.g.:

data <- MASS::Cars93[18:47, ] %>%
  select(Manufacturer, Model, Type, Sales = Price)

reactable(
  data,
  defaultExpanded = TRUE,
  paginateSubRows = TRUE,
  groupBy = "Manufacturer",
  searchable = TRUE,
  columns = list(
    Manufacturer = colDef(footer = "Total"),
    Sales = colDef(
      aggregate = "sum",
      format = colFormat(currency = "USD"),
      footer = JS("function(column, state) {
        let total = 0
        state.sortedData.forEach(function(row) {
          // Ignore grouped rows
          if (row._subRows) {
            return
          }
          total += row[column.id]
        })
        return total.toLocaleString('en-US', { style: 'currency', currency: 'USD' })
      }")
    )
  ),
  defaultColDef = colDef(footerStyle = list(fontWeight = "bold"))
)

This is included in a few examples on the custom rendering doc page, but it could definitely use better documentation.