R Shiny DT表格分页时下拉框选择后跳转首页问题求助
Shiny DT表格分页时选择下拉框自动跳回首页问题解决
问题描述
开发的R Shiny DT表格包含分页功能、内嵌下拉选择框,支持保存更新后的表格为CSV文件。但切换到非首页后,选择下拉框选项时页面会自动跳回首页。
解决方案
核心问题是下拉框触发数据更新时,表格不必要的重绘导致分页状态丢失,同时存在数据修改逻辑冗余。以下是修复后的完整代码及关键改动说明:
关键改动
- 移除冗余的
editData调用,避免重复修改数据触发表格重绘 - 确保
replaceData的resetPaging = FALSE参数正确生效,保留当前分页位置 - 优化JavaScript中行索引的存储与读取,避免分页时DOM节点索引和实际数据行索引不匹配
- 删除不必要的事件响应式对象及监听逻辑,减少无效的依赖触发
修复后完整代码
library(shiny) library(tibble) library(DT) # 读取数据(替换为你的文件路径) data <- read.csv("C:/Users/jyang29/Downloads/saved_data.csv") ui <- fluidPage( DTOutput("myDataTable"), actionButton('update', 'Refresh Table'), actionButton("saveBtn", "Save as CSV") ) server <- function(input, output, session) { # 响应式存储数据 rv <- reactiveValues(data = data) # 渲染DataTable output$myDataTable <- renderDataTable({ datatable( rv$data, editable = TRUE, escape = FALSE, selection = 'none', options = list( columnDefs = list(list( targets = 5, render = JS( "function(data, type, row, meta) {", " if (type === 'display') {", " var dropdownValue = data;", " var rowId = meta.row;", " return '<select class=\"dropdown\" data-row=\"' + rowId + '\">' +", " '<option value=\"setosa\"' + (dropdownValue === 'setosa' ? ' selected' : '') + '>setosa</option>' +", " '<option value=\"versicolor\"' + (dropdownValue === 'versicolor' ? ' selected' : '') + '>versicolor</option>' +", " '<option value=\"virginica\"' + (dropdownValue === 'virginica' ? ' selected' : '') + '>virginica</option>' +", " '</select>';", " }", " return data;", "}" ) )), preDrawCallback = JS( "function() {", " Shiny.unbindAll(this.api().table().node());", "}" ), drawCallback = JS( "function() {", " Shiny.bindAll(this.api().table().node());", "}" ), initComplete = JS( "function(settings, json) {", " var api = this.api();", " $('.dropdown').on('mousedown', function(e) { e.stopPropagation(); });", " $('#myDataTable').on('change', '.dropdown', function() {", " var selectedValue = $(this).val();", " var rowId = $(this).data('row');", " Shiny.setInputValue('dropdown_edit', {", " row: rowId + 1,", " col: 5,", " value: selectedValue", " }, {priority: 'event'});", " });", "}" ), buttons = list( 'copy', 'print', list( extend = 'collection', buttons = c('csv', 'excel', 'pdf'), text = 'Download' ) ) ) ) }, server = TRUE) # 表格代理 proxy <- dataTableProxy('myDataTable') # 监听下拉框修改事件 observeEvent(input$dropdown_edit, { info <- input$dropdown_edit i <- info$row j <- info$col k <- info$value # 更新响应式数据 isolate({ rv$data[i, j] <- DT::coerceValue(k, rv$data[i, j]) }) # 更新表格,保留分页状态 replaceData(proxy, rv$data, resetPaging = FALSE) }) # 刷新表格按钮 observeEvent(input$update, { replaceData(proxy, rv$data, resetPaging = FALSE) }) # 保存为CSV observeEvent(input$saveBtn, { write.csv(rv$data, "C:/Users/jyang29/Downloads/saved_data.csv", row.names = FALSE) }) } shinyApp(ui, server)
说明
- 将下拉框修改事件改为独立的
dropdown_edit,避免和DT内置的单元格编辑逻辑冲突 - 使用
data-row属性存储DataTable原生的行索引,解决分页时DOM行索引和数据行索引不匹配的问题 - 简化数据更新流程,仅修改目标单元格并通过
replaceData局部更新表格,避免重绘整个表格导致分页重置
内容的提问来源于stack exchange,提问作者Jian Yang
相关产品推荐
相关产品推荐

