user7353167
user7353167

Reputation:

Selectizeinput inputs be mutually exclusive R Shiny

I have to use multiple selectizeinputs for the same variable. When i choose one category one bla1, the category should excluded in bla2. How do i archieve that?Is there an option to link two selectizeinputs?

ui <- fluidPage(

   # Application title
   titlePanel("Old Faithful Geyser Data"),

   # Sidebar with a slider input for number of bins 
   sidebarLayout(
      sidebarPanel(
         sliderInput("bins",
                     "Number of bins:",
                     min = 1,
                     max = 50,
                     value = 30),
         selectizeInput("bla1", "muh", choices = faithful$waiting, multiple = TRUE),
         selectizeInput("bla2", "muh2", choices = faithful$waiting, multiple = TRUE)
      ),

      # Show a plot of the generated distribution
      mainPanel(
         plotOutput("distPlot")
      )
   )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

   output$distPlot <- renderPlot({
      # generate bins based on input$bins from ui.R
      x    <- faithful[, 2] 
      bins <- seq(min(x), max(x), length.out = input$bins + 1)

      # draw the histogram with the specified number of bins
      hist(x, breaks = bins, col = 'darkgray', border = 'white')
   })
}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 3

Views: 625

Answers (3)

Jan Net&#237;k
Jan Net&#237;k

Reputation: 324

After some experimentation with isolate(), I think I have found a pretty solution. You can try it with:

shiny::runGist("https://gist.github.com/netique/499c0117f092d43980b1c8ea52671499")

Source:

library(shiny)

shinyApp(
  ui = fluidPage(
    selectInput("left", "left",
      choices = LETTERS[1:10],
      multiple = TRUE, selectize = FALSE, size = 10
    ),
    selectInput("right", "right",
      choices = LETTERS[1:10],
      multiple = TRUE, selectize = FALSE, size = 10
    )
  ),
  server = function(input, output) {
    observeEvent(
      input$right,
      {
        updateSelectInput(
          inputId = "left",
          choices = setdiff(LETTERS[1:10], isolate(input$right)),
          selected = isolate(input$left)
        )
      }
    )
    observeEvent(
      input$left,
      {
        updateSelectInput(
          inputId = "right",
          choices = setdiff(LETTERS[1:10], isolate(input$left)),
          selected = isolate(input$right)
        )
      }
    )
  }
)

Upvotes: 0

user7353167
user7353167

Reputation:

ui <- fluidPage(

  # Application title
  titlePanel("Old Faithful Geyser Data"),

  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30),
      selectizeInput("bla1", "muh", choices = faithful$waiting, multiple = TRUE),
      htmlOutput("bla2")
    ),

    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output) {



  output$bla2 <- renderUI({
    ## filter choices to anything NOT selected by bla1
    choices <- faithful$waiting[!faithful$waiting %in% input$bla1]
    selected <- input$bla2
    selectizeInput("bla2", "muh2", choices = choices, multiple = TRUE, selected = selected)
  })

  output$distPlot <- renderPlot({
    # generate bins based on input$bins from ui.R
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    # draw the histogram with the specified number of bins
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

This code was posted by a guy and it is the best solution. The only thing is that when I click in "input$bla2" i lose the focus on the field when i enter a value. Probably because it renders again every time. Anyone an idea how to overcome that problem?

Upvotes: 2

cirofdo
cirofdo

Reputation: 1074

You first need to define your input on server side. And then, just do a little trick to get the avaiable options:

ui <- fluidPage(

  # Application title
  titlePanel("Old Faithful Geyser Data"),

  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins",
                  "Number of bins:",
                  min = 1,
                  max = 50,
                  value = 30),
      uiOutput("bla1_ui"),  # here just for defining your ui
      uiOutput("bla2_ui")
    ),

    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

# Define server logic required to draw a histogram
server <- function(input, output) {
  # and here you deal with your desired input
  output$bla1_ui <- renderUI({
    selectizeInput("bla1", "muh", choices = faithful$waiting, multiple = TRUE)
  })

  output$bla2_ui <- renderUI({

    avaiable <- faithful$waiting
    if(!is.null(input$bla1))
      avaiable <- faithful$waiting[-which(faithful$waiting %in% input$bla1)]

    selectizeInput("bla2", "muh2", choices=avaiable, multiple = TRUE)
  })

  output$distPlot <- renderPlot({
    # generate bins based on input$bins from ui.R
    x    <- faithful[, 2] 
    bins <- seq(min(x), max(x), length.out = input$bins + 1)

    # draw the histogram with the specified number of bins
    hist(x, breaks = bins, col = 'darkgray', border = 'white')
  })
}

# Run the application 
shinyApp(ui = ui, server = server)

Upvotes: 1

Related Questions