shinyWidgets icon indicating copy to clipboard operation
shinyWidgets copied to clipboard

updatePickerInput updates selected only after closing the input

Open trafficonese opened this issue 4 years ago • 1 comments

I need a pickerInput which allows to select max. 2 different groups. Since there is no option for this restriction, I came up with a server-part using updatePickerInput. But interestingly, the selection is only updated, when the picker-dropdown is closed and reopened again. So I had to use shinyjs and run selectpicker("refresh") via runjs to work correctly. Shouldn't updatePickerInput call the refresh method itself?

Here is an example of my problem where the shinyjs::runjs line is commented out.

library(shiny)
library(shinyjs)
library(shinyWidgets)

kennwertmap <- data.frame(vals=c("v", "vfree", "vref", "t", "state", "index", "index1", "index2"),
                          grp=c("v","v","v",
                                "t","s",
                                "ix","ix","ix"), stringsAsFactors = FALSE)


ui <- fluidPage(
  useShinyjs(),
  splitLayout(cellWidths = c("30%", "70%"),
              div(style = "height: 1000px;",
                  pickerInput(("value"), "Auswahl",
                              choices = list(
                                v = c(`mean v` = "v",
                                      `mean v free` = "vfree",
                                      `mean v ref` = "vref"),
                                t = c(`time` = "t"),
                                s = c(state = "state"),
                                i = c(index = "index", 
                                      index1 = "index1",
                                      index2 = "index2")
                              ),
                              selected = 1, multiple = TRUE,
                              options = pickerOptions(liveSearch = TRUE, 
                                                      selectOnTab = TRUE))
              ),
              div(
                verbatimTextOutput("txt"),
                verbatimTextOutput("txt1")
              )
  )
  
)

server <- function(input, output, session) {
  kennwert <- reactiveValues(a = NULL)
  observe({
    if (is.null(input$value)) {
      kennwert$a <- NULL
    } else {
      isolate({
        knwn <- input$value
        mappedkenw <- kennwertmap[kennwertmap$vals %in% knwn, ]
        if (is.null(kennwert$a)) {
          kennwert$a <- mappedkenw 
        } else {
          ## Check if 2 Groups already selected
          if (length(unique(mappedkenw$grp)) > 2) {
            
            ## Grp to Remove          
            firstgrp <- kennwert$a[kennwert$a$grp != unique(kennwert$a$grp)[2],]
            
            ## Add One if new
            newone <- setdiff(mappedkenw[,"vals"], kennwert$a$vals)
            newone <- kennwertmap[kennwertmap$vals %in% newone, ]
            
            newgrp <- rbind(firstgrp, newone)
            kennwert$a <- newgrp 
            updatePickerInput(session, "value", selected = newgrp$vals)
            # delay(100, shinyjs::runjs(HTML('$("#value").selectpicker("refresh")')))
            
          } else {
            ## Add One if new
            newone <- setdiff(mappedkenw[,"vals"], kennwert$a$vals)
            if (length(newone) != 0) {
              newone <- kennwertmap[kennwertmap$vals %in% newone, ]
              kennwert$a <- rbind(kennwert$a, newone)
            }
            ## Remove One
            lessone <- setdiff(kennwert$a$vals, mappedkenw[,"vals"])
            if (length(lessone) != 0) {
              kennwert$a <- kennwert$a[kennwert$a$vals != lessone,]
            }            
          }
        }
      })
      
    }
  })
  
  output$txt <- renderPrint({
    print(input$value)
  })
  output$txt1 <- renderPrint({
    print(kennwert$a)
  })
}

shinyApp(ui, server)

trafficonese avatar Jun 23 '20 05:06 trafficonese

Humm selectpicker("refresh") is called by the update method, I'll lokk into it. Have you tried to modify the bindings to make it work ?

Victor

pvictor avatar Jun 30 '20 08:06 pvictor