Reputation: 2899
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
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)
Upvotes: 3