Home > Software engineering >  How can I render and remove UI in a Shiny App depending on a textInput and some conditions?
How can I render and remove UI in a Shiny App depending on a textInput and some conditions?

Time:11-15

I want to render UI depending on a textInput() and some conditions. Like when the number of chars in my textInput() is greater than 2 and also matches a value from a variable of a dataset, i want to render the new UI. Otherwise when the number of chars is samller than 3, the UI should be removed. But somehow the UI is permanently removed/not visible even if both conditions are TRUE. What do i miss here?

library(shiny)
library(tidyverse)

data = starwars

ui = fluidPage(
  
  textInput("txt", "Look up name"),
  uiOutput(outputId = "new"),
  
  
)

server = function(input, output, session){

  res = reactive({data%>%filter(str_detect(name, input$txt))%>%slice_min(order_by = birth_year, n = 3)%>%pull(name)})

  observeEvent(input$txt, {
    if(str_detect(paste(res(), collapse = " "), input$txt) & nchar(input$txt) > 2){
      
      output$new <- renderUI({
        div(id = "new",
            map(.x = res(), .f = ~div(.x)))
      })
      
    }else if(nchar(input$txt) < 3){
      
      removeUI(selector = "#new")
      
      }
    })
}
shinyApp(ui, server)

CodePudding user response:

Perhaps you should just return(NULL) as shown below or give a different id to your div(id="new2").

library(shiny)
library(tidyverse)

#data <- starwars

ui = fluidPage(
  
  textInput("txt", "Look up name"),
  uiOutput(outputId = "new")
  
)

server = function(input, output, session){
  
  res <- eventReactive(input$txt, {
    req(input$txt)
    starwars %>% dplyr::filter(str_detect(name, input$txt)) %>%
      dplyr::slice_min(order_by = birth_year, n = 3) %>% pull(name)
  })
  
  observeEvent(input$txt, {
    if(str_detect(paste(res(), collapse = " "), input$txt) & nchar(input$txt) > 2){
      
      output$new <- renderUI({
        div(id = "new",
            map(.x = res(), .f = ~div(.x)))
      })
      
    }else { # if(nchar(input$txt) < 3){
      output$new <- renderUI({return(NULL)})
      #removeUI(selector = "#new2")  ###  different id also works
      
    }
  })
}
shinyApp(ui, server)
  • Related