单元格编辑后如何保持DT(DataTables)的行展开/折叠状态?
保持DT行组的展开/折叠状态
要解决编辑单元格后行组全部展开的问题,核心思路是在更新数据前记录当前行组的展开状态,数据更新后再恢复这些状态,具体实现如下:
实现步骤
- 前端通过JS监听行组的点击事件,将每个行组的展开状态同步到Shiny输入对象中
- 在后端处理单元格编辑、更新数据后,调用自定义JS代码根据记录的状态恢复行组的展开/折叠
修改后的完整代码
library(shiny) library(DT) ui <- fluidPage( titlePanel("Collapse/Expand table"), mainPanel( tabsetPanel( tabPanel("table1", dataTableOutput("my_table")) ) ) ) server <- function(input, output, session) { myData <- mtcars[1:15, 1:5] output$my_table <- DT::renderDataTable({ datatable( myData, extensions = 'RowGroup', options = list(rowGroup = list(dataSrc = 3), pageLength = 20), callback = JS( # 初始化时折叠所有行组 "table.one('init', () => $('#my_table .dtrg-group').trigger('click'));", # 监听行组点击,同步状态到Shiny输入 "table.on('click', 'tr.dtrg-group', function () {", " var groupIndex = $(this).index('.dtrg-group');", " var isExpanded = !$(this).nextUntil('.dtrg-group').hasClass('hidden');", " Shiny.setInputValue('group_states', {index: groupIndex, expanded: isExpanded});", "});" ), selection = 'none', editable = 'cell' ) }) # 存储行组的展开状态 groupStates <- reactiveVal(list()) observeEvent(input$group_states, { states <- groupStates() states[[as.character(input$group_states$index)]] <- input$group_states$expanded groupStates(states) }) proxy = dataTableProxy("my_table") observeEvent(input$my_table_cell_edit, { info = input$my_table_cell_edit myData <<- editData(myData, info) replaceData(proxy, myData, resetPaging = FALSE, clearSelection = FALSE) # 恢复行组状态 isolate({ states <- groupStates() if(length(states) > 0){ session$sendCustomMessage("restore_group_states", states) } }) }) # 接收恢复状态的消息,执行前端操作 observeEvent(input$restore_group_states, { runjs( "var states = Shiny.inputBindings.get('shiny.action').getValue('restore_group_states');", "$('.dtrg-group').each(function(index) {", " var isExpanded = states[index.toString()];", " var rows = $(this).nextUntil('.dtrg-group');", " if(isExpanded === false && !rows.hasClass('hidden')) {", " rows.addClass('hidden');", " } else if(isExpanded === true && rows.hasClass('hidden')) {", " rows.removeClass('hidden');", " }", "});" ) }) } # Run the application shinyApp(ui = ui, server = server)
代码说明
- 前端状态跟踪:点击行组时,将行组的索引和展开状态通过
Shiny.setInputValue传给后端,存储到groupStates响应式变量中 - 数据更新后恢复:调用
replaceData更新数据后,通过自定义消息将存储的状态传回前端,遍历行组并恢复对应的展开/折叠状态 - 初始化折叠:保留了原代码中初始化时折叠所有行组的逻辑
内容的提问来源于stack exchange,提问作者Odrai
相关产品推荐
相关产品推荐

