Reputation: 2043
In running the code posted at the bottom a table is rendered with rhandsontable whereby the user can add columns via click of the actionButton()
, can add/delete rows by right-click of mouse when hovering over the table, and where the bottom row provides column sums.
However as illustrated below, values in inserted rows are not picked up in the column totals. Is there a way to have the column totals add up all rows even as they expand/contract? Without going through the brain damage of setting up rowNames
(or row.names
) as reactives?
Code:
library(rhandsontable)
library(shiny)
rowNames <- c('Hello A','Hello B','Hello C','Hello D','Total')
data <- data.frame(row.names = rowNames,'Col 1' = c(10,20,-5,18,43),check.names = FALSE)
ui <- fluidPage(br(),
rHandsontableOutput('hottable'),br(),
actionButton("addCol", "Add column"),br(),br()
)
server <- function(input, output) {
uiTable <- reactiveVal(data)
observeEvent(input$hottable,{uiTable(hot_to_r(input$hottable))})
output$hottable <- renderRHandsontable({
rhandsontable(uiTable(),rowHeaderWidth = 100, useTypes = TRUE)
})
observe({
req(input$hottable)
DF <- hot_to_r(input$hottable)
DF[setdiff(rowNames, "Total"),]
DF["Total",] <- colSums(DF[setdiff(rowNames, "Total"),, drop = FALSE], na.rm = TRUE)
uiTable(DF)
})
observeEvent(input$addCol, {
newCol2 <- data.frame(c(10,20,-5,18,43))
names(newCol2) <- paste("Col", ncol(hot_to_r(input$hottable)) + 1)
uiTable(cbind(uiTable(), newCol2))
})
}
shinyApp(ui,server)
Upvotes: 0
Views: 91
Reputation: 2043
Very simple, I should have thought about it more before posting this. But maybe some other newbie will benefit from this. In the observe()
function just replace rowNames
(the list used to assign row names to the original dataframe) with rownames(DF)
(which reads the actual names of the dataframe rows in its current state of play as it's being modified). Here´s the complete revised observer:
observe({
req(input$hottable)
DF <- hot_to_r(input$hottable)
DF[setdiff(rownames(DF), "Total"),]
DF["Total",] <- colSums(DF[setdiff(rownames(DF),"Total"),, drop = FALSE], na.rm = TRUE)
uiTable(DF)
})
Upvotes: 1