Обновить варианты выбора в динамически сгенерированном selectizeInput (ах) с учетом выбранного значения в предыдущем selectizeInput (ах)

#r #shiny

#r #блестящий

Вопрос:

Я динамически генерирую несколько selectizeInputs на основе реактивного значения и пытаюсь ограничить выбор в выпадающем списке 2, удалив выбранное значение dropdown1 из доступных вариантов в выпадающем списке 2. Решение должно распространяться на все динамически сгенерированные n выпадающих списков, т.Е. Для выпадающего списка 3 доступными вариантами должны быть все LETTERS , кроме A и B (при условии, что выбор в выпадающем списке 1 равен, A а выбор в выпадающем списке 2 равен B ). Если пользователь изменяет выбор в выпадающем списке 1 на Z then A , он должен стать доступным в выборе для выпадающего списка 3.

У меня возникли некоторые проблемы при попытке сделать это, я пытаюсь сделать это в renderUI, сначала создав реактивные значения для хранения входных данных, а затем используя setdiff для ограничения выбора. Я знаю updateSelectizeInput() , что могу обновлять варианты, но это может стать довольно подробным по мере увеличения количества выпадающих списков. Заранее благодарим вас за помощь и предложения.

См. reprex:

 ui <- fluidPage(
  numericInput(inputId = "ndropdowns", label = "Number of dropdowns", value = 1),
  uiOutput("dropdowns")
)

server <- function(input, output, session){
  
  output$dropdowns <- renderUI({
    uiDropdowns <- vector(mode = "list", length = input$ndropdowns)
    for(i in seq_along(uiDropdowns) ){
     uiDropdowns[[i]] <- tagList(
        selectizeInput(inputId = paste0("dropdown", i), label =  paste0("dropdown", i), choices = setdiff(LETTERS,  selectedCols$values))
      )
    }
    uiDropdowns
  })
  
  selectedCols <- reactiveValues(values = NULL)
  
  observe({
    isolate({
    selectedCols$values <- c(input$dropdown1, input$dropdown2, input$dropdown3)
    })
  })
}


shinyApp(ui, server)
  

Ответ №1:

Это может быть один из способов приблизиться к этому, основываясь на том, что у вас уже есть. Для каждого из ваших входов используйте updateSelectizeInput в цикле и удаляйте выбранные элементы с каждым входом. Это включает в себя настройку selected так, чтобы входные данные не изменяли значение при изменении другого ввода (если только значение больше невозможно для более близких входных данных).

 library(shiny)

ui <- fluidPage(
  numericInput(inputId = "ndropdowns", label = "Number of dropdowns", value = 1),
  uiOutput("dropdowns")
)

server <- function(input, output, session){
  
  output$dropdowns <- renderUI({
    uiDropdowns <- vector(mode = "list", length = input$ndropdowns)
    for(i in seq_along(uiDropdowns) ){
      uiDropdowns[[i]] <- tagList(
        selectizeInput(inputId = paste0("dropdown", i), label =  paste0("dropdown", i), choices = LETTERS)
      )
    }
    uiDropdowns
  })
  
  observe({
    current_selections <- sapply(1:input$ndropdowns, function(i) input[[paste0("dropdown", i)]])
    choice_set <- c()
    uiDropdowns <- vector(mode = "list", length = input$ndropdowns)
    for(i in seq_along(uiDropdowns) ){
      updateSelectizeInput(session, paste0("dropdown", i), choices = setdiff(LETTERS, choice_set), selected = current_selections[i])
      choice_set <- c(choice_set, input[[paste0("dropdown", i)]])
    }
  })
  
}

shinyApp(ui, server)