Reputation: 95
I have two checkboxGroupInputs and I would like the two update in tandem. In other words, updating one should update the other, but then updating the other should keep what the first selected and then just continue updating the selections. Bu updating, I mean providing the choice values.
The toy example provides an illustrative case, however, here we can clearly see that when I am done updating the first, and the continuous updating the second box, the first box resets. I want to avoid this resetting. Also, it should not matter if the user starts selecting in the first or the second box. The procedure should be invariant to that.
I have tried two approaches, one using the updateCheckboxGroupInput function, and using reactives (commeted out).
Any suggestions are welcomed:
library(shiny)
# Shiny server object
# Define UI for app
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
uiOutput("boxes"),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
textOutput(outputId = "TestText")
)
)
)
age.values <- 1:10
server <- function(input, output, session) {
# define reactive
age <- reactiveVal()
age(age.values)
valuesMax <- reactiveVal()
valuesMin <- reactiveVal()
valuesMin(age.values)
valuesMax(age.values)
# v <- age[which(!age %in% valuesMin[1:2])]
# v
# Sidebar panel for inputs ----
# update reactives
# if valuesMax updates then update valuesMin
# observeEvent(input$go, {
#
# # define valuesMin whatever values is remaining
# v <- age()[which(!age() %in% input$age.bins.max)]
#
# valuesMin(v)
#
# })
#
# observeEvent(input$go, {
#
# # define valuesMin whatever values is remaining
# w <- age()[which(!age() %in% input$age.bins.min)]
#
# valuesMax(w)
#
# })
##### 0. Pre-processing ####
output$boxes <- renderUI({
sidebarPanel(
checkboxGroupInput(inputId = "age.bins.min",
"Select mono decreasing age groups",
choiceNames = paste("age group", age()),
choiceValues = age(),
inline = T,
selected=character(0)),
checkboxGroupInput(inputId = "age.bins.max",
"Select mono increasing age groups ",
choiceNames = paste("age group", age()),
choiceValues = age(),
inline = T,
selected=character(0)),
actionButton(inputId = "go",
label = "Update"))
})
observe({
x <- input$age.bins.min
# Can use character(0) to remove all choices
if (is.null(x))
x <- character(0)
w <- age()[which(!age() %in% x)]
# Can also set the label and select items
updateCheckboxGroupInput(session, "age.bins.max",
label = paste("age group", w),
choices = w,
selected = character(0))
})
observe({
y <- input$age.bins.max
# Can use character(0) to remove all choices
if (is.null(y))
y <- character(0)
v <- age()[which(!age() %in% y)]
# Can also set the label and select items
updateCheckboxGroupInput(session, "age.bins.min",
label = paste("age group", v),
choices = v,
selected = character(0))
})
# output$TestText <- renderText({
# max <- paste("valuesMax", valuesMax())
# min <- paste("valuesMin", valuesMin())
#
# print(max)
# #print(min)
#
#
# })
#
}
# Create Shiny app ----
shinyApp(ui = ui, server = server)
Upvotes: 0
Views: 297
Reputation: 18551
I am not sure what you are trying to do, but does the following solve your problem?
For dealing with min and max range values I prefer the inputSlider but, then again, I am not sure what you are trying to achieve.
Update
There seemed to be a problem with observeEvent not updating when input values changed from an integer value to NULL. I now rewrote the two observeEvent
statements as one observe
and it works now also when deselecting values.
library(shiny)
# Shiny server object
# Define UI for app
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
uiOutput("boxes"),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
textOutput(outputId = "TestText")
)
)
)
age.values <- 1:10
server <- function(input, output, session) {
# Sidebar panel for inputs ----
output$boxes <- renderUI({
sidebarPanel(
checkboxGroupInput(inputId = "age.bins.min",
"Select mono decreasing age groups",
choiceNames = paste("age group", age()),
choiceValues = age(),
inline = T,
selected = character(0)),
checkboxGroupInput(inputId = "age.bins.max",
"Select mono increasing age groups ",
choiceNames = paste("age group", age()),
choiceValues = age(),
inline = T,
selected = character(0)),
actionButton(inputId = "go",
label = "Update"))
})
# define reactive
age <- reactiveVal(age.values)
observe({
x <- input$age.bins.min
if (is.null(x))
x <- character(0)
y <- input$age.bins.max
if (is.null(y))
y <- character(0)
w1 <- age()[!(age() %in% y)]
w1n <- if(length(w1)==0) character(0)
else paste("age group", w1)
w2 <- age()[!(age() %in% x)]
w2n <- if(length(w2)==0) character(0)
else paste("age group", w2)
updateCheckboxGroupInput(session, "age.bins.min",
choiceNames = w1n,
choiceValues = w1,
selected = x)
updateCheckboxGroupInput(session, "age.bins.max",
choiceNames = w2n,
choiceValues = w2,
selected = y)
})
}
# Create Shiny app ----
shinyApp(ui = ui, server = server)
Upvotes: 1