Reputation: 23
According the examples in the official documentation of selectizeGroup-module, I can do something like this:
library(shiny)
library(shinyWidgets)
library(dplyr)
data("mpg", package = "ggplot2")
ui <- fluidPage(
fluidRow(
column(
width = 10, offset = 1,
tags$h3("Filter data with selectize group"),
panel(
selectizeGroupUI(
id = "my-filters",
params = list(
manufacturer = list(inputId = "manufacturer", title = "Manufacturer:"),
model = list(inputId = "model", title = "Model:"),
trans = list(inputId = "trans", title = "Trans:"),
class = list(inputId = "class", title = "Class:")
)
),
status = "primary"
),
DT::dataTableOutput(outputId = "table")
)
)
)
server <- function(input, output, session) {
mpgView2 <- reactive({
mpg
})
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mpgView2,
vars = c("manufacturer", "model", "trans", "class")
)
output$table <- DT::renderDataTable({
req(res_mod())
res_mod()
})
}
shinyApp(ui, server)
And the filters work perfect. My requirement also tells me that this table needs to be editable, hide some columns, format round, etc. I'd usually do something like this:
mpgView1 <- reactive({
DT::datatable(
mpg,
filter = "none",
selection = "none",
style = "bootstrap",
extensions = c("Scroller", "FixedColumns"),
options = list(
dom = 't',
scrollY = 500,
scrollX = 400,
scroller = TRUE,
defRender = TRUE,
autoWidth = TRUE,
targets = "no-sort",
bSort = FALSE,
order = c(),
fixedColumns = list(leftColumns = 2),
columnDefs = list(
list(
visible = FALSE,
targets = c(0)
),
list(
width = "50px",
targets = "_all"
)
)
),
editable = list(
target = 'cell',
disable = list(columns = c(0,1,2))
)
) %>%
DT::formatRound(
columns = c(3)
)
})
output$table <- DT::renderDataTable({
mpgView1()
})
But now I'm not sure how to "combine" both functionalities. If I do try to put mpgView1() inside res_mod, I get an error:
Warning: Error in as.data.frame.default: cannot coerce class ‘c("datatables", "htmlwidget")’ to a data.frame
I appreciate any help. Thanks.
Upvotes: 2
Views: 1104
Reputation: 10365
The output of selectizeGroupServer
is your filtered data as a reactive, so you can just use this output in the datatable
call that is styled to your needs. The requirement that the datatable is editable brings some problems: selectizeGroupServer
needs to know the new data. That is possible, however in my solution the table refreshes completely and existing filters are lost. I think you could try to get a bit nicer behaviour with a proxy
, but then the combination of the proxy
and selectizeGroupServer
is a bit trickier.
library(shiny)
library(shinyWidgets)
library(dplyr)
#>
#> Attache Paket: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
data("mpg", package = "ggplot2")
ui <- fluidPage(
fluidRow(
column(
width = 10, offset = 1,
tags$h3("Filter data with selectize group"),
panel(
selectizeGroupUI(
id = "my-filters",
params = list(
manufacturer = list(inputId = "manufacturer", title = "Manufacturer:"),
model = list(inputId = "model", title = "Model:"),
trans = list(inputId = "trans", title = "Trans:"),
class = list(inputId = "class", title = "Class:")
)
),
status = "primary"
),
DT::dataTableOutput(outputId = "table")
)
)
)
server <- function(input, output, session) {
mpgView2 <- reactiveVal(mpg)
observeEvent(input$table_cell_edit, {
cell <- input$table_cell_edit
updated_data <- mpgView2()
updated_data[cell$row, cell$col] <- cell$value
mpgView2(updated_data)
})
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mpgView2,
vars = c("manufacturer", "model", "trans", "class")
)
output$table <- DT::renderDataTable({
req(res_mod())
DT::datatable(
res_mod(),
filter = "none",
selection = "none",
style = "bootstrap",
extensions = c("Scroller", "FixedColumns"),
options = list(
dom = 't',
scrollY = 500,
scrollX = 400,
scroller = TRUE,
defRender = TRUE,
autoWidth = TRUE,
targets = "no-sort",
bSort = FALSE,
order = c(),
fixedColumns = list(leftColumns = 2),
columnDefs = list(
list(
visible = FALSE,
targets = c(0)
),
list(
width = "50px",
targets = "_all"
)
)
),
editable = list(
target = 'cell',
disable = list(columns = c(0,1,2))
)
) %>%
DT::formatRound(
columns = c(3)
)
})
}
shinyApp(ui, server)
Created on 2020-08-26 by the reprex package (v0.3.0)
Upvotes: 1