Reputation: 103
I'd like to have one pickerinput limit the options in the Selectize Group module of ShinyWisgets. I can get that to work using a reactive expression. However, nothing is produced in the table for me to view the results. What am I missing?
I suspect I made an error in the mpg_filter expression.
# https://dreamrs.github.io/shinyWidgets/reference/selectizeGroup-module.html
library(shiny)
library(shinyWidgets)
data("mpg", package = "ggplot2")
ui <- fluidPage(
fluidRow(
column(
width = 10, offset = 1,
tags$h3("Filter data with selectize group"),
panel(
pickerInput(
inputId = "car_select",
choices = unique(mpg$manufacturer),
options = list(
`live-search` = TRUE,
title = "None selected"
),
),
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"
),
dataTableOutput(outputId = "table")
)
)
)
server <- function(input, output, session) {
mpg_filter <- reactive({
mpg %>%
filter(mpg$manufacturer %in% input$car_select)
})
res_mod <- reactive({
callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mpg_filter(),
vars = c("manufacturer", "model", "trans", "class")
)
})
output$table <- renderDataTable(res_mod())
}
shinyApp(ui, server)
Upvotes: 3
Views: 502
Reputation: 12839
Since v0.5.0 (November 2019),
selectizeGroupServer()
(moduleselectizeGroup
) now accept reactive data and reactive vars arguments, see examples for details?selectizeGroupServer
.
The last example in ?selectizeGroupServer
is effectively a direct answer to this question:
# Subset data -------------------------------------------------------------
library(shiny)
library(shinyWidgets)
data("mpg", package = "ggplot2")
ui <- fluidPage(
fluidRow(
column(
width = 10, offset = 1,
tags$h3("Filter data with selectize group"),
panel(
pickerInput(
inputId = "car_select",
choices = unique(mpg$manufacturer),
options = list(
`live-search` = TRUE,
title = "None selected"
)
),
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) {
mpg_filter <- reactive({
subset(mpg, manufacturer %in% input$car_select)
})
res_mod <- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mpg_filter,
vars = c("manufacturer", "model", "trans", "class")
)
output$table <- DT::renderDataTable({
req(res_mod())
res_mod()
})
}
shinyApp(ui, server)
Note data = mpg_filter
(the reactive itself, not a call to it) in callModule(module = selectizeGroupServer)
Outdated answer
The difficulty stems from the fact that selectizeGroupServer
does not accept a reactive
as the data
argument. If it did, it would be simpler. Here is a workaround:
server <- function(input, output, session) {
mpg_filter <- reactive({
mpg %>%
filter(mpg$manufacturer %in% input$car_select)
})
res_mod <- reactive({})
observe({
res_mod <<- callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mpg_filter(),
vars = c("manufacturer", "model", "trans", "class")
)
})
output$table <- renderDataTable(res_mod())
}
Here is another one:
server <- function(input, output, session) {
mpg_filter <- reactive({
mpg %>%
filter(mpg$manufacturer %in% input$car_select)
})
res_mod <- reactive({
callModule(
module = selectizeGroupServer,
id = "my-filters",
data = mpg_filter(),
vars = c("manufacturer", "model", "trans", "class")
)
})
output$table <- renderDataTable(res_mod()())
}
Note the only change: res_mod()()
. This is because res_mod()
itself is a reactive, since callModule
is wrapped in reactive
(not just res_mod
itself, but the resulting call), so we have to call it twice like res_mod()()
.
This doesn't happen in the first suggestion, but I had to hack a bit with the initialization of res_mod
, and then <<-
, to avoid a bug when res_mod
is called while still undefined.
I would still go with the first, since res_mod()()
is too far from idiomatic Shiny code.
Upvotes: 3