Reputation: 1722
I have an app where a user chooses a file name from a drop-down menu (selectizeInput
) and confirms the choice with an actionButton
. The app will display the results in the DT::dataTableOutput
format.
I'd like to be able to show a loading screen (using shinydashboardloader
package) but only AFTER a user presses the actionButton
. Prior that I'd like to show an empty screen. Additionally, if a user wants to try several files in one session, the loading screen should appear every time the actionButton
has been pressed and disappear when the dataset has been loaded.
Currently, if I run this app the loading button appears all the time, also before a user makes a file choice
### ui.R
library(shiny)
library(shinydashboard)
library(DT)
library(shinycustomloader)
dashboardPage(
dashboardHeader(),
dashboardSidebar(
selectizeInput("file", "Select File",
c("fileA", "fileB")),
actionButton("submit", "Submit")
),
dashboardBody(
fluidRow(
box(h2("My Data"),
div(style = 'overflow-x: scroll',
withLoader(DT::dataTableOutput('mytable'),
type = "html",
loader = "loader1")),
width = 12)
)
)
)
#### server.R
library(shiny)
library(shinydashboard)
library(DT)
shinyServer(function(input, output, session) {
file_name <- reactive({
req(input$file)
})
# When the Submit button is clicked, start the cleaning and matching
observeEvent(input$submit, {
## open chosen file
# open_file <- read_excel(paste0("input_files/", file_name()))
### + some processing that gives me matched_df
matched_df <- data.frame(A = c(1, 2, 3, 4),
B = c("A", "B", "C", "D"))
selected <- reactive({
matched_df # + apply some filter
})
output$mytable = DT::renderDataTable({
selected()
})
})
})
I'm guessing that the way forward would be to use conditionalPanel
but I'm not sure how to make a click on the actionButton
a condition.
I applied conditionalPanel
to the datatable, but it works only the first time I press "Submit" button. If in the same session I change the file name and press the button again, the loader won't appear. Any ideas how I can make it work multiple times in one session?
dashboardBody(
fluidRow(
box(h2("My Data"),
conditionalPanel("input.submit==1",
div(style = 'overflow-x: scroll',
withLoader(DT::dataTableOutput('mytable'),
type = "html",
loader = "loader1"))
),
width = 12)
Any help will be great, thanks!
Upvotes: 3
Views: 2656
Reputation: 12155
1: I'm not familiar with shinydashboardloader
but I was able add a loading indicator to my app by using the shinyjs
package to hide and show elements using CSS. I would add your loading page elements to your main page and wrap them in a shinyjs::hidden
function so they're hidden by default. Then when the user clicks the action button, call shinyjs::showElement
to show them and shinyjs::hideElement
to hide them once loading is complete.
UI:
shinyjs::hidden(div(id = 'loading',
# PUT LOADING ELEMENTS HERE))
SERVER:
observeEvent(input$submit, {
# Show element once submit button is pressed
shinyjs::showElement(id = 'loading')
# CODE TO MAKE DATA FRAME
# Hide loading element when done
shinyjs::hideElement(id = 'loading')
)
2: As for your problem with your edit, the reason that your conditional panel only shows the first time is that the value of an actionButton
increases by one each time it is clicked. So the first time it is clicked it goes from 0 to 1; if you click it again it goes from 1 to 2 and so on. Since you set the condition to input$select == 1
, it will only appear if the button has been clicked exactly 1 time.
To get it to do what you want, you either need to change the condition to input$select > 1
so that it appears as long as the button has been clicked once, or add a reactiveValue
that gets set to 1 when the button is clicked and then resets to 0 when another condition is met (like when loading finishes).
rv <- reactiveValues(loading = 0)
# When you click submit, show the loading screen
observeEvent(input$submit, {rv$loading <- 1})
# When you click LOAD, start loading, then hide the loading screen when finished
observeEvent(input$LOAD, {
# CODE TO LOAD AND GENERATE DATA HERE
rv$loading <- 0})
Upvotes: 3