如何修复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, {})内的逻辑:
- 使用
freezeReactiveValue冻结input$file的响应,防止重置过程中临时触发下游响应式变量计算报错 - 用Shiny原生的
session$sendInputMessage重置fileInput的输入状态,无需引入shinyjs - 直接将需要清除的daterange、PAGE2日历、分类下拉框、表格、图表等输出直接赋值为NULL,即可隐藏对应组件,仅保留
fileInput
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

