Reputation: 167
Steps to replicate my problem:
Choice 1 has pre-selected options, while Choice 2 is blank by default.
When a selection is made in Choice 1, that option is removed in the drop down list for Choice 2.
I would like to be able to order my selections, but they always go back to the original order. How do I prevent this from happening?
library(shiny)
library(flexdashboard)
# UI ----------
ui <- fluidPage(
uiOutput("Select1"),
uiOutput("Select2"))
# Server -------------
server <- function(input, output, session) {
vals <- reactiveValues(sel1 = character(),
sel2 = character())
observeEvent(input$Select1, {
vals$sel1 = input$Select1
})
observeEvent(input$Select2, {
vals$sel2 = input$Select2
})
output$Select1 <- renderUI({
letters = c("A", "B", "C", "D", "E", "F", "G")
selected = c("A", "B", "C")
if (length(vals$sel1) != 0 && vals$sel1 %in% letters) {
selected = vals$sel1
}
selectizeInput('Select1', label = "Choice 1:",
multiple = TRUE,
choices = letters[!letters %in% input$Select2],
selected = selected,
options = list(plugins = list('remove_button', 'drag_drop')))
})
output$Select2 <- renderUI({
letters = c("A", "B", "C", "D", "E", "F", "G")
selected <- NULL
if (length(vals$sel2) != 0 && vals$sel2 %in% letters) {
selected = vals$sel2
}
selectizeInput('Select2', label = "choice 2:",
multiple = TRUE,
choices = letters[!letters %in% input$Select1],
selected = selected,
options = list(plugins = list('remove_button', 'drag_drop')))
})
}
shinyApp(ui = ui, server = server)
Using isolate() around selected doesn't work. I was able to get the ordering to work with the following code, but then lost the ability to preserve my selections.
observeEvent(input$Select1, {
# Allows reordering of columns
if (!all(vals$sel1 %in% input$Select1)) {
vals$sel1 = input$Select1
}
})
observeEvent(input$Select2, {
# Allows reordering of columns
if (!all(vals$sel2 %in% input$Select2)) {
vals$sel2 = input$Select2
}
})
Can anyone help?
Upvotes: 1
Views: 946
Reputation: 21349
Perhaps orderInput()
from shinyjqui
package might be useful in your case. Please note that if in your use case you have too many choices in select3, you may need to reconsider. Try this
library(shiny)
library(shinyjqui)
### UI ----------
ui <- fluidPage(
orderInput(inputId = 'select1', 'Choice 1: ', items = LETTERS[1:3], connect = c("select3", "select2")),
orderInput(inputId = 'select2', 'Choice 2: ', items = NULL, connect = c("select1", "select3"), placeholder = 'Drag item here...'),
orderInput(inputId = 'select3', 'Choose items', items = LETTERS[4:7], connect = c("select1", "select2")),
verbatimTextOutput("t1")
)
server <- function(input, output) {
output$t1 <- renderPrint({input$select1})
}
shinyApp(ui, server)
Upvotes: 1
Reputation: 3646
Basically, you are recreating the UI element every time the input selects which causes the selections to be sorted. I personally would probably consider using updateSelectizeInput
because rendering them dynamically on the server side sort of undermines the point of selectize.
That being said, you can add a req
statement to your code to prevent them from the dynamic UI from re-rendering unless the values are actually changed (or there are none to cover initial rendering)
output$Select1 <- renderUI({
req(!all(vals$sel1 %in% input$Select1) | is.null(input$Select1), cancelOutput = TRUE)
letters = c("A", "B", "C", "D", "E", "F", "G")
...<<other code>>...
})
output$Select2 <- renderUI({
req(!all(vals$sel2 %in% input$Select2) | is.null(input$Select1), cancelOutput = TRUE)
letters = c("A", "B", "C", "D", "E", "F", "G")
...<<other code>>...
})
Upvotes: 2