Reputation: 161
In the simple example below, I cannot select state 3 after selecting states 1 and 2. It works okay with 2 states, but as soon as I go to three states it infinite loops through the ObserveEvents. If it were the triggers from updating, I'd expect it to infinitely loop after selecting just the first state, but it doesn't.
I came across the freezeReactiveValue()
function but when I freeze the reactiveValues
in an attempt to not run the observeEvent
, the selectizes don't update to prevent the user from selecting the same state twice.
Any ideas?
STATES <- c("AL", "AK", "AZ", "AR", "CA", "CO", "CT",
"DE", "DC", "FL", "GA", "HI", "ID", "IL",
"IN", "IA", "KS", "KY", "LA", "ME", "MD",
"MO", "MT", "NE", "NV", "NH", "NJ", "NM",
"NY","NC", "ND", "OH", "OK", "OR", "PA",
"PR", "RI", "SC", "SD", "TN", "TX", "UT",
"VT", "VA", "VI", "WA", "WV", "WI", "WY")
ui <- fluidPage(fluidRow(
selectizeInput("state1", label = "State",
choices = STATES,
selected = NULL,
multiple = FALSE,
options = list(placeholder = "Select a State",
onInitialize = I('function() { this.setValue(""); }'))),
selectizeInput("state2", label = "State",
choices = STATES,
selected = NULL,
multiple = FALSE,
options = list(placeholder = "Select a State",
onInitialize = I('function() { this.setValue(""); }'))),
selectizeInput("state3", label = "State",
choices = STATES,
selected = NULL,
multiple = FALSE,
options = list(placeholder = "Select a State",
onInitialize = I('function() { this.setValue(""); }')))
))
server <- function(input, output, session) ({
observeEvent(input$state1, {
updateSelectizeInput(
session, "state2",
choices = setdiff(STATES,
c(input$state1, input$state3)),
selected = input$state2
)
updateSelectizeInput(
session, "state3",
choices = setdiff(STATES,
c(input$state1, input$state2)),
selected = input$state3
)
})
observeEvent(input$state2, {
updateSelectizeInput(
session, "state1",
choices = setdiff(STATES,
c(input$state2, input$state3)),
selected = input$state1
)
updateSelectizeInput(
session, "state3",
choices = setdiff(STATES,
c(input$state1, input$state2)),
selected = input$state3
)
})
observeEvent(input$state3, {
updateSelectizeInput(
session, "state1",
choices = setdiff(STATES,
c(input$state2, input$state3)),
selected = input$state1
)
updateSelectizeInput(
session, "state2",
choices = setdiff(STATES,
c(input$state1, input$state3)),
selected = input$state3
)
})
})
shinyApp(ui = ui, server = server)
Upvotes: 1
Views: 184
Reputation: 9108
As you already noticed, the onInitialize = I('function() { this.setValue(""); }')
causes the infinite loop since it gets called every time when updateSelectizeInput
runs.
As an alternative you could do the following: Since the value of the selectizeInput
shall be set to ""
when starting the app, you can also set choices = NULL
inside your ui
. This will automatically set the initial value to ""
. In order for then making the elements of STATES
selectable, put them into an reactiveVal
inside your server
states <- reactiveVal(STATES)
and set the choices
parameter of the updateSelectizeInput
such that it uses states()
:
choices = setdiff(states(), c(input$state1, input$state3))
Notice that for the below MWE I also corrected a presumed typo in your last updateSelectizeInput
(set selected = input$state2
instead of input$state3
).
STATES <- c("AL", "AK", "AZ", "AR", "CA", "CO", "CT",
"DE", "DC", "FL", "GA", "HI", "ID", "IL",
"IN", "IA", "KS", "KY", "LA", "ME", "MD",
"MO", "MT", "NE", "NV", "NH", "NJ", "NM",
"NY","NC", "ND", "OH", "OK", "OR", "PA",
"PR", "RI", "SC", "SD", "TN", "TX", "UT",
"VT", "VA", "VI", "WA", "WV", "WI", "WY")
ui <- fluidPage(fluidRow(
selectizeInput(
"state1",
label = "State",
choices = NULL,
selected = NULL,
multiple = FALSE,
options = list(placeholder = "Select a State")
),
selectizeInput(
"state2",
label = "State",
choices = NULL,
selected = NULL,
multiple = FALSE,
options = list(placeholder = "Select a State")
),
selectizeInput(
"state3",
label = "State",
choices = NULL,
selected = NULL,
multiple = FALSE,
options = list(placeholder = "Select a State")
)
))
server <- function(input, output, session)
({
states <- reactiveVal(STATES)
observeEvent(input$state1, {
updateSelectizeInput(
session,
"state2",
choices = setdiff(states(),
c(input$state1, input$state3)),
selected = input$state2
)
updateSelectizeInput(
session,
"state3",
choices = setdiff(states(),
c(input$state1, input$state2)),
selected = input$state3
)
})
observeEvent(input$state2, {
updateSelectizeInput(
session,
"state1",
choices = setdiff(states(),
c(input$state2, input$state3)),
selected = input$state1
)
updateSelectizeInput(
session,
"state3",
choices = setdiff(states(),
c(input$state1, input$state2)),
selected = input$state3
)
})
observeEvent(input$state3, {
updateSelectizeInput(
session,
"state1",
choices = setdiff(states(),
c(input$state2, input$state3)),
selected = input$state1
)
updateSelectizeInput(
session,
"state2",
choices = setdiff(states(),
c(input$state1, input$state3)),
selected = input$state2
)
})
})
shinyApp(ui = ui, server = server)
Upvotes: 1