使用 RowReorder 扩展时如何保留新的表顺序以便重新计算?

问题描述 投票:0回答:1

我有一个带有计算列的数据表。我希望 RShiny 用户能够更改此数据表中的行顺序,并根据新的表顺序重新计算列。

在数据表中使用“RowReorder”扩展看起来应该能够实现这一点。但是,当我设置

server = T
时,当我尝试拖放时,行顺序会立即恢复为原始状态,而当我设置
server = F
时,行会重新排序,但列不会重新计算。

我当前的代码如下。我认为这可能是由于

order = list(list(0, 'asc'))
每次都强制执行相同的顺序,但当这只是
order = list()
时,问题仍然存在。

suppressPackageStartupMessages({
  library(tidyverse)
  library(shiny)
  library(shinyhelper)
  library(sortable)
  library(shinyWidgets)
  library(DT)
})

data <- data.frame(Type = c("A", "B", "C", "D"),
                   Value = c(100, 90, 80, 70)) %>%
                     mutate(calculate = Value - lag(Value))

ui <- function(){
  
  fluidPage(
    
    dataTableOutput("table")
    
  )
    
}


server <- function(input, output){
  
  updated_data <- reactiveVal(data)
  
  observeEvent(input$table_row_reorder, {
               
               updated_data(updated_data()[input$table_row_reorder$order, ])
               
               updated_data$calculate <- updated_data()$Value - lag(updated_data()$Value)
  
  })
  
  output$table <- renderDT(server = T, 
                           data,
                           colnames = c("ID" = 1),
                           extensions = 'RowReorder',
                           options = list(rowReorder = TRUE, order = list(list(0, 'asc'))))
  
}

shinyApp(ui, server)
shiny datatables dt shiny-reactivity
1个回答
0
投票

没有闪亮值

input$table_row_reorder
。因此,为了在行重新排序后获得新订单,必须监听 JavaScript 事件
row-reorder
,它提供有关行重新排序的详细信息,并且必须使用
Shiny.setInputValue
将此新订单发送到 Shiny 服务器。然后可以使用
replaceData
更新表格。

library(shiny)
library(DT)
library(dplyr)

dat <- data.frame(Type = c("A", "B", "C", "D"),
                  Value = c(100, 90, 80, 70)) %>%
  mutate(calculate = Value - lag(Value))

js <- c(
  "table.on('row-reorder', function(e, details, edit) {",
  "  var order = [0, 1, 2, 3];",
  "  for(entry of details) {",
  "    order[entry.newPosition] = entry.oldPosition;",
  "  }",
  "  Shiny.setInputValue('newOrder', order);",
  "});"
)


ui <- fluidPage(
  br(),
  DTOutput("table")
)

server <- function(input, output, session){
  
  output$table <- renderDT({
    datatable(
      dat,
      extensions = 'RowReorder',
      callback = JS(js),
      options = list(rowReorder = TRUE, order = list(list(0, 'asc')))
    )
  }, server = TRUE)
  
  proxy <- dataTableProxy("table")
  
  Dat <- reactiveVal(dat)
  
  observeEvent(input$newOrder, {
    dat0 <- Dat()
    dat1 <- dat0[input$newOrder + 1, ]
    dat1$calculate <- dat1$Value - lag(dat1$Value)
    
    replaceData(proxy, dat1, resetPaging = FALSE, rownames = TRUE)
    
    Dat(dat1)
  })
  
}

shinyApp(ui, server)
© www.soinside.com 2019 - 2024. All rights reserved.