You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Shiny代码中reset按钮功能,使其点击后仅保留fileInput组件

Shiny Reset按钮功能修复方案

核心调整逻辑:

  • 重置时优先清空文件输入状态,触发所有依赖上传文件的组件自动失效
  • 无需额外依赖库,直接将需要隐藏的UI输出赋值为NULL即可清除对应组件
  • 加入freezeReactiveValue避免重置过程中响应式变量中间状态触发报错

完整修改后代码

library(shiny)
library(shinythemes)
library(readxl)
library(dplyr)
library(openxlsx)

ui <- fluidPage(
  
  shiny::navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
                    br(),
                    tabPanel("PAGE1",
                             sidebarLayout(
                               sidebarPanel(
                                 uiOutput('fileInput'),
                                 uiOutput('daterange'),
                                 actionButton("reset", "Reset")
                               ),
                               mainPanel(
                                 dataTableOutput('table')
                               )
                             )),
                    
                    tabPanel("PAGE2",
                             sidebarLayout(
                               sidebarPanel(
                                 uiOutput('date'),
                                 uiOutput("mycode")
                                 
                               ),
                               mainPanel(
                                 tabsetPanel(
                                   tabPanel("", plotOutput("graph",width = "100%", height = "600")
                                   )
                                 ))
                             ))))

server <- function(input, output,session) {
  
  output$fileInput <- renderUI({
    fileInput("file",h4("Import file"), multiple = T, accept = ".xlsx")
  })
  
  sheetnames <- eventReactive(input$file, {
    available_sheets = openxlsx::getSheetNames(input$file$datapath)
  })
  
  data <- reactive({
    if (is.null(input$file)) {
      return(NULL)
    }
    
    else {
      df3 <- read_excel(input$file$datapath,sheetnames()[1])
      validate(need(all(c('date1', 'date2') %in% colnames(df3)), "Incorrect file"))  
      df4 <- df3 %>% mutate_if(~inherits(., what = "POSIXct"), as.Date) 
      return(df4)
    }
  })
  
  data2 <- reactive({
    req(input$file)
    df1 <- read_excel(input$file$datapath,sheetnames()[2])
    df1
  })
  
  output$daterange <- renderUI({
    req(data())
    dateRangeInput("daterange1", "Period you want to see:",
                   min = min(data()$date2),
                   max = max(data()$date2))
  })
  
  data_subset <- reactive({
    req(input$daterange1)
    req(input$daterange1[1] <= input$daterange1[2])
    days <- seq(input$daterange1[1], input$daterange1[2], by = 'day')
    subset(data(), date2 %in% days)
  })
  
  output$table <- renderDataTable({
    data_subset()
  })
  
  
  output$date <- renderUI({
    req(data2())
    all_dates <- seq(as.Date('2021-01-01'), as.Date('2021-01-15'), by = "day")
    disabled <- as.Date(setdiff(all_dates, as.Date(data2()$date2)), origin = "1970-01-01")
    entrydate<- dateInput(input = "Date2", 
                          label = h4("Choose"),
                          min = min(data2()$date2),
                          max = max(data2()$date2),
                          format = "dd-mm-yyyy",
                          datesdisabled = disabled)
    entrydate$children[[2]]$attribs$placeholder <- "No selected date"
    entrydate
  })
  
  output$mycode <- renderUI({
    req(input$Date2)
    df1 <- data2()
    df5 <- df1[as.Date(df1$date2) %in% input$Date2,]
    selectInput("code", label = h4("Category"),choices=c("No code selected" = "", sort(unique(df5$Category))))
  })
  
  output$graph <- renderPlot({
    req(input$Date2,input$code,data2())
    df1 <- data2()
    if (input$code=="") return(NULL)
    
    plot(x=df1$DR02,y=df1$DR1)
  })
  
  observeEvent(input$reset, {
    # 冻结响应式值避免重置过程触发中间报错
    freezeReactiveValue(input, "file")
    # 原生方法重置文件输入控件
    session$sendInputMessage("file", list(type = "reset"))
    # 清空所有需要移除的UI组件
    output$daterange <- renderUI({NULL})
    output$date <- renderUI({NULL})
    output$mycode <- renderUI({NULL})
    output$table <- renderDataTable({NULL})
    output$graph <- renderPlot({NULL})
  })
}

shinyApp(ui = ui, server = server) 

关键调整说明

仅修改了observeEvent(input$reset, {})内的逻辑:

  1. 使用freezeReactiveValue冻结input$file的响应,防止重置过程中临时触发下游响应式变量计算报错
  2. 用Shiny原生的session$sendInputMessage重置fileInput的输入状态,无需引入shinyjs
  3. 直接将需要清除的daterange、PAGE2日历、分类下拉框、表格、图表等输出直接赋值为NULL,即可隐藏对应组件,仅保留fileInput

内容的提问来源于stack exchange,提问作者Antonio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:45:04