0

I am trying to create an app that will show you results depending on a selectInput and the changes are controlled by actionButtons.

When you launch the app, you have to select a choice: Data 1 or Data 2. Once you have selected your choice (e.g. Data 1), you have to click the actionButton "submit type of data". Next, you go to the second tab, choose a column and then click "submit". The output will be: one table, one text and one plot.

image 1

Then, if you go back to the first tab and select "Data 2", everything that you have generated is still there (as it is expected, since you didn't click any button).

image 2

However, I would like to remove everything that is in the mainPanel if I change my first selectInput as you could see it when you launch the app for the first time. The idea is that since you have changed your first choice, you will have to do the same steps again (click everything again).

image 3

I would like to preserve and control the updates with actionButtons as I have in my code (since I am working with really long datasets and I don't want to depend on the speed of loading things that I don't want until I click the button). Nevertheless, I cannot think a way to remove everything from mainPanel if I change the choice of the first selectInput.

Does anybody have an idea how I can achieve this?

Thanks in advance

Code:

library(shiny)
library(shinyWidgets)
library(shinyFeedback)
library(DT)
library(datasets)

ui <- fluidPage(
  sidebarPanel(
    tabsetPanel(id="histogram",
                
                tabPanel("Selection",
                         
                  useShinyFeedback(),
                  selectInput(inputId = "type", label = "Select your data", 
                              choices =  c("Data 1" = "data1",
                                           "Data 2" = "data2")),
                  conditionalPanel(
                    condition = "input.type == 'data2'",
                    div(style = "position:absolute;right:2.5em;",
                        actionButton(
                          inputId = "button_more_info_data2",
                          label = "More info",
                          icon = icon("info-circle"))
                    )
                  ),
                  
                  actionButton(
                    inputId = "button",
                    label = "Submit type of data",
                    icon = icon("check")
                  )
                ), 
              tabPanel("Pick the column",
                       br(),
                       selectizeInput(inputId = "list_columns", label = "Choose the column:", choices=character(0)),
                       
                       actionButton(
                         inputId = "button2",
                         label = "Submit")
              ))
      
    
    
  ),
  mainPanel(
    dataTableOutput("table"),
    textOutput("text"),
    plotOutput("myplot")
  )
)

server <- function(input, output, session) {
  
  observeEvent(input$type,{
    feedbackWarning(inputId = "type",
                    show = ("data2" %in% input$type),
                    text ="This data is... Please, be careful..."
    )
  })
  
  mydata <- reactive({
    if(input$type == "data1"){
      mtcars
    }else{
      iris
    }
    
  }) %>% bindEvent(input$button2)
  
  
  # This is to generate the choices (gene list) depending on the user's input.
  observeEvent(input$button, {
    updateSelectizeInput(
      session = session,
      inputId = "list_columns",
      choices = colnames(trees), options=list(maxOptions = length(colnames(trees))),
      server = TRUE
    )
  })
  
  output$table <- renderDataTable({
    req(input$button2)
    mydata()
    })
  
  output$text <- renderText({
    req(input$button2)
    input$list_columns
    })
  
  output$myplot <- renderPlot({
    req(input$button2, input$button)
    hist(trees[,input$list_columns])
  })
}

if (interactive())
  shinyApp(ui, server)
emr2
  • 1,436
  • 7
  • 23
  • Would't it make sense to reset the `mainPanel` outputs once the Selection-tab is reselected (or simply implement a reset button)? Also check [bindCache](https://shiny.rstudio.com/app-stories/weather-lookup-caching.html). – ismirsehregal Aug 18 '22 at 13:02
  • Yes, that is what I want, I would like to reset the `mainPanel` outputs, but not when the Selection-tab is reselected (because you can go to the tab and not change the `selectInput` for some reason). Is it possible? or will I need to have a reset button? (Btw, thanks for the additional info, I didn't know about `bindCache`) – emr2 Aug 18 '22 at 13:43

1 Answers1

0

Here is an example using a reset button - using the selectInput you'll end up with a circular reference:

library(shiny)
library(shinyWidgets)
library(shinyFeedback)
library(DT)
library(datasets)

ui <- fluidPage(sidebarPanel(tabsetPanel(
  id = "histogram",
  tabPanel(
    "Selection",
    useShinyFeedback(),
    selectInput(
      inputId = "type",
      label = "Select your data",
      choices =  c("Data 1" = "data1",
                   "Data 2" = "data2")
    ),
    conditionalPanel(
      condition = "input.type == 'data2'",
      div(
        style = "position:absolute;right:2.5em;",
        actionButton(
          inputId = "button_more_info_data2",
          label = "More info",
          icon = icon("info-circle")
        )
      )
    ),
    actionButton(
      inputId = "button",
      label = "Submit type of data",
      icon = icon("check")
    ),
    actionButton(
      inputId = "reset",
      label = "Reset",
      icon = icon("xmark")
    )
  ),
  tabPanel(
    "Pick the column",
    br(),
    selectizeInput(
      inputId = "list_columns",
      label = "Choose the column:",
      choices = character(0)
    ),
    
    actionButton(inputId = "button2",
                 label = "Submit")
  )
)),
mainPanel(
  dataTableOutput("table"),
  textOutput("text"),
  plotOutput("myplot")
))

server <- function(input, output, session) {
  observeEvent(input$type, {
    feedbackWarning(
      inputId = "type",
      show = ("data2" %in% input$type),
      text = "This data is... Please, be careful..."
    )
  })
  
  mydata <- reactiveVal(NULL)
  
  observe({
    if (input$type == "data1") {
      mydata(mtcars)
    } else if (input$type == "data2") {
      mydata(iris)
    } else {
      mydata(data.frame())
    }
  }) %>% bindEvent(input$button2)
  
  observeEvent(input$reset, {
    mydata(data.frame())
  })
  
  # This is to generate the choices (gene list) depending on the user's input.
  observeEvent(input$button, {
    updateSelectizeInput(
      session = session,
      inputId = "list_columns",
      choices = colnames(trees),
      options = list(maxOptions = length(colnames(trees))),
      server = TRUE
    )
  })
  
  output$table <- renderDataTable({
    req(input$button2)
    mydata()
  })
  
  output$text <- renderText({
    req(input$button2)
    input$list_columns
  })
  
  output$myplot <- renderPlot({
    req(input$button2, input$button)
    hist(trees[, input$list_columns])
  })
}

shinyApp(ui, server)
ismirsehregal
  • 30,045
  • 5
  • 31
  • 78
  • Thanks very much for your help and reply! It is almost what I want, but it doesn't reset everything since the plot and the text remain. And I would like to have the `mainPanel` completely empty. I saw that I could use `shinyjs` to hide the plots and text (https://stackoverflow.com/a/43715740/13997761) but it doesn't work with `req()`. – emr2 Aug 22 '22 at 06:57
  • @emr2 the above should show the general procedure as your example isn't really minimal. Just apply the same strategy to the other outputs. Btw. why are you using another dataset for them (`trees`)? – ismirsehregal Aug 22 '22 at 07:06