首页 > 解决方案 > shiny: apply shinycustomerloader after pressing actionButton

问题描述

BACKGROUND

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.

OBJECTIVE

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.

CURRENT STATE

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.

UPDATE

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!

标签: rshinyshinydashboard

解决方案


1:我不熟悉,shinydashboardloader但我可以通过使用包来向我的应用程序添加一个加载指示器,以shinyjs使用 CSS 隐藏和显示元素。我会将您的加载页面元素添加到您的主页并将它们包装在一个shinyjs::hidden函数中,以便它们默认隐藏。然后,当用户单击操作按钮时,调用shinyjs::showElement以显示它们并shinyjs::hideElement在加载完成后隐藏它们。

用户界面:

shinyjs::hidden(div(id = 'loading',
           # PUT LOADING ELEMENTS HERE))

服务器:

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:至于您的编辑问题,您的条件面板只显示第一次的原因是actionButton每次单击时a的值都会增加一个。所以第一次点击它时,它会从 0 变为 1;如果再次单击它,它将从 1 变为 2,依此类推。由于您将条件设置为input$select == 1,因此仅当按钮已被准确单击 1 次时才会出现。

要让它做你想做的事,你要么需要将条件更改input$select > 1为,只要单击按钮一次,它就会出现,或者添加一个在reactiveValue单击按钮时设置为 1,然后在单击按钮时重置为 0满足另一个条件(例如加载完成时)。

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})

推荐阅读