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

R Shiny DT新增行时自动生成递增Reference.Number方法

实现方案

核心调整点:将表格数据改为响应式存储,每次点击添加按钮前先计算当前表格内参考编号的最大值,自动生成递增的新编号填入新行,再同步更新表格和存储的数据,避免编号重复、断号问题。


具体修改逻辑

  • 把初始静态数据集改为响应式值存储,实时同步用户新增、编辑后的最新表格内容,避免无法获取修改后数据的问题
  • 废弃提前写死的空行模板,每次触发添加动作时,实时读取当前表格的Reference.Number列,转成数值后取最大值加1,生成新的连续参考编号
  • 新增行后同步更新响应式存储的表格数据,保证下一次点击添加时,计算最大值的数据源是最新状态
  • 补充单元格编辑同步逻辑,避免用户手动修改已有参考编号后,新生成的编号出现冲突

修改后可直接运行的完整代码

library(shiny)
library(shinythemes)
library(shinyWidgets)
library(shinyanimate)
library(DT)
library(tidyverse)

# 初始示例数据
df <- structure(list(Reference.Number = c("33331", "33332", "33333", 
                                          "33334", "33335"), 
                     Request.Date = c("1/6/2022", "1/6/2022", "1/19/2022", 
                                      "1/20/2021", "1/24/2022"), 
                     Requestor.Name = c("Comm Dist 3 by Kitty", "Comm Dist 3 by Kitty", "Updated maps for David", "    Stone Cold", "Updated SOE 60 inch wall map"),
                     Requestor.Dept.Div = c("C 3 Staff",    "C 3 Staff", "Unincorp & Comm", "Mt.Rushmore AME Church Ft. Billy",                                         "SOE"), 
                     Requestor.Phone = c("", "", "", "", ""), 
                     Contact.Person = c("Tommy",                             "Tommy", "Bob", "Bob", "Joe"),
                     Contact.Phone = c("1111",                               "2222", "3333", "ext 1111", "3434"),
                     Deadline = c("1/20/2022",         "1/20/2022", "1/22/2022", "", "1/24/2022"),
                     Project.Description = c("45x36 portrait map ",          "45x36 portrait map  ",   "24x24 Unincorporated areas", "Percent Females Aged 25 - 55  Below Poverty Level By Zip Code",                "SOE Wall Map 60x60 p"), 
                     Project.File.Location = c("", 
                                               "", "C:\\ABC\\Tommy\\work|Map-Projects\\BD Unincororated\\#14785 Unincorporated 24x24.pdf", 
                                               "C:\\ABC\\Demographics\\Demographic_Request\\FemalesAge10-18BelowPoveryLevel\\FemalesAge10-18BelowPoveryLevel.aprx", 
                                               "C:\\ABC\\Tommy\\work|Map-Projects\\BD Unincororated\\#14786 V P 60x60.pdf"
                     ), PDF.File.....Map.Name.... = c("", "", "", "C:\\ABC\\Demographics\\Demographic_Request\\FemalesAge10-18BelowPoveryLevel\\pdfs\\MapNo14785.pdf", 
                                                      ""), Assigned.To = c("", "", "", "", ""), Completion.Date = c("", 
                                                                                                                     "", "", "", ""), Notes = c(NA, NA, NA, NA, NA), Year = c(2022, 
                                                                                                                                                                               2022, 2022, 2022, 2022)), class = "data.frame", row.names = c(NA, -5L)) 

# UI部分保持原有逻辑不变
ui =   navbarPage(tags$style("table, .table {color: unset;} .dataTable th, .datatables input {color: white}"),
                  title = div("GIS Team Projects"),
                  theme = shinytheme("cyborg"),
                  tabPanel("GIS Projects",
                           icon = icon("info"),
                           div(p(h1("Instructions:"),style="text-align: justify;")),
                           p("1. The user can add their project details.", style="color:black"),
                           uiOutput("all"),
                           sidebarLayout(
                             sidebarPanel(
                               actionButton("addData", "Add Project Details"),
                             ),
                             mainPanel(
                               downloadButton("download1","Download data as csv"),                
                               DTOutput("contents")),)
                  )
)

server <- function(input, output) {
  # 用响应值存储表格全量数据,实时同步最新状态
  rv <- reactiveValues(
    table_data = df
  )
  
  # 渲染可编辑表格
  output$contents = renderDT({
    rv$table_data
  },
  server = FALSE,
  editable = TRUE,
  options = list(lengthChange = TRUE),
  rownames = FALSE)
  
  # 创建表格代理对象
  proxy = dataTableProxy(outputId = "contents")
  
  # 监听添加按钮点击事件
  observeEvent(input$addData, {
    # 提取当前所有参考编号,转数值后取最大值
    current_max_ref <- max(as.numeric(rv$table_data$Reference.Number), na.rm = TRUE)
    # 生成下一个连续编号,保持字符型和原格式一致
    new_ref_num <- as.character(current_max_ref + 1)
    
    # 生成新空行,仅填充参考编号,其余字段为空
    new_row <- rv$table_data[1, ]
    new_row[1, ] <- NA
    new_row$Reference.Number <- new_ref_num
    # 统一字符型字段空值格式,和原表保持一致
    new_row <- new_row %>% mutate(across(where(is.character), ~ifelse(is.na(.), "", .)))
    
    # 向表格添加新行
    proxy %>% addRow(new_row)
    # 同步更新响应值里的表格数据,保证下一次计算编号使用最新数据
    rv$table_data <- rbind(rv$table_data, new_row)
  })
  
  # 同步单元格编辑内容到响应值,避免手动修改编号后新编号生成错误
  observeEvent(input$contents_cell_edit, {
    edit_info <- input$contents_cell_edit
    rv$table_data[edit_info$row, edit_info$col] <- edit_info$value
  })
  
  # 补全原代码缺失的下载功能逻辑
  output$download1 <- downloadHandler(
    filename = function() {
      paste0("GIS_project_records_", Sys.Date(), ".csv")
    },
    content = function(file) {
      write.csv(rv$table_data, file, row.names = FALSE, fileEncoding = "UTF-8")
    }
  )
}

# 启动应用
shinyApp(ui = ui, server = server)

补充说明

如果后续参考编号需要增加前缀(比如PROJ-33335这类格式),只需要调整编号提取、拼接的规则即可,核心的响应式存储数据、实时计算最大值的逻辑不需要改动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 02:30:54