Mark
Mark

Reputation: 2899

delete verbatimtextOutput

ran into this weird issue when teaching a student about shiny programming.

What i wanted was to make code that deletes the verbatimtextOuput element, rather than print an empty value

This is the code he wrote, but it deletes all buttons, the whole UI basically. Can this be done? I know more complex options like conditional panels etc, but just trying to figure out why removeUI doesn't do what I expected here.

Thanks!

app:

library(shiny)

ui<-fluidPage(  h5("Hello there"),      #First text on the window
               br(),                            #empty line
               actionButton(inputId = "ClickonMe", label = "Make data"),  # button 1
               actionButton(inputId = "ClickonMe2", label = "Print data"), # button 2
               actionButton(inputId = "ClickonMe3", label = "Transform data"),

               verbatimTextOutput("Response_text")  #reactive text output    )

server <- function(input,output) {
     values <- reactiveValues()
     observeEvent(input$ClickonMe,
               values$name <- TRUE   )
     observeEvent(input$ClickonMe3,
               if (values$name == TRUE) { values$name <- FALSE}
               else { values$name <- TRUE}   )
     observeEvent(input$ClickonMe2,
               if (values$name == TRUE) { output$Response_text <- renderPrint( isolate({values$name}) ) }
               else  if (values$name == FALSE)  {  removeUI(
                 selector = "div:has(> #Response_text)"
               )
               }

  )    }

shinyApp(ui, server)

EDIT VERSION:

changed pork chops answer a little so that this version removes and remakes the verbatim element in the ui. What i now try to fully understand is, is why the piece req(....) has such an impact. the print(values$name) proofs that the variable exist, and the observer sees it, yet if you # the req( ) line, suddenly the app stops recreating the verbatimtextouput after it has been removed the first time. Hope I can learn why this is the case. Thank you!

library(shiny)

ui <- fluidPage(  
  h5("Hello there"),                                          # First text on the window
  br(),                                                       # empty line
  actionButton(inputId = "ClickonMe", label = "Make data"),   # button 1
  actionButton(inputId = "ClickonMe2", label = "Print data"), # button 2
  actionButton(inputId = "ClickonMe3", label = "Transform data"),
  mainPanel(verbatimTextOutput("Response_text"))
)

server <- function(input,output,session) {
  values <- reactiveValues()
  values$name <- T

  observeEvent(input$ClickonMe,{
    values$name <- T 
  })

  observeEvent(input$ClickonMe3,{
    if (values$name){ values$name <- F}
    else{ values$name <- T }
  })

  observeEvent(input$ClickonMe2,{

    print(values$name)
  output$Response_text <- renderPrint({ isolate({ 

    req(values$name)
    if(!values$name){
      removeUI(
        selector = "div:has(> #Response_text)"
      )
    }else {
    as.character(values$name)}
  })
      })

})
}

Upvotes: 1

Views: 709

Answers (1)

Pork Chop
Pork Chop

Reputation: 29417

1) First of all please have a look at the Google's R Style Guide when writing code and try to stick to it I think both you and your students will benefit from it.

2) Use curly braces too when using functions such as observeEvent and renderPrint

3) Familiarise yourself with req function which is very handy

Sample Code how to remove UI:

library(shiny)

ui <- fluidPage(  
  h5("Hello there"),                                          # First text on the window
  br(),                                                       # empty line
  actionButton(inputId = "ClickonMe", label = "Make data"),   # button 1
  actionButton(inputId = "ClickonMe2", label = "Print data"), # button 2
  actionButton(inputId = "ClickonMe3", label = "Transform data"),
  mainPanel(verbatimTextOutput("Response_text"))
)

server <- function(input,output,session) {
  values <- reactiveValues()
  values$name <- NULL

  observeEvent(input$ClickonMe,{
    values$name <- T 
  })

  observeEvent(input$ClickonMe3,{
    if (values$name){ 
      values$name <- F}
    else{
      values$name <- T
    }
  })

  observeEvent(input$ClickonMe2,{
    if (values$name){ 
      values$name <- F
      }
    else{
      values$name <- T
    }
  })

  output$Response_text <- renderPrint({
    req(values$name)
    if(!values$name){
      removeUI(
        selector = "div:has(> #Response_text)"
      )
    }
    as.character(values$name)})
}

shinyApp(ui, server)

enter image description here

Upvotes: 3

Related Questions