首页 > 解决方案 > Shiny - 更改 DT 表中的列名以存储为 reactiveVal

问题描述

我有一个带有 DT 数据表的 Shiny 应用程序,我可以在其中通过 Javascript 更改列名(感谢另一个 Stackoverflow 条目)。我想将更改后的列名存储在 reactiveVal 中。但是,这目前不起作用。

这是我使用的当前代码:

library(shiny)
library(DT)

callback <- c(
  "table.on('dblclick.dt', 'thead th', function(e) {",
  "  var $th = $(this);",
  "  var index = $th.index();",
  "  var colname = $th.text(), newcolname = colname;",
  "  var $input = $('<input type=\"text\">')",
  "  $input.val(colname);",
  "  $th.empty().append($input);",
  "  $input.on('change', function(){",
  "    newcolname = $input.val();",
  "    if(newcolname != colname){",
  "      $(table.column(index).header()).text(newcolname);  ",
  "      Shiny.onInputChange('newColumnValue', newcolname);",
  "      console.log( newcolname);",
  "    }",
  "    $input.remove();",
  "  }).on('blur', function(){",
  "    $(table.column(index).header()).text(newcolname);",
  "    $input.remove();",
  "  });",
  "});"
 )

 ui <- fluidPage(
   textOutput("value"),
   tags$head(
   tags$link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/jquery-   contextmenu/2.8.0/jquery.contextMenu.min.css"),
   tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.8.0/jquery.contextMenu.min.js")
  ),
  DT::dataTableOutput("table")

)

server <- function(input, output){
  val <- reactiveVal(NULL) 

  mydata <- reactive({
    browser()
    data <- datatable(iris[1:3,], callback = JS(callback))
    val(colnames(data$x$data))
    data
  })

  output$table <- DT::renderDataTable({
    mydata()
  }, server = FALSE) 

  output$value <- renderText({
    val()                     
    })
 }

 shinyApp(ui, server)

但是,我的 reactiveVal 变量没有任何变化。我需要改变什么?

干杯,安迪

标签: rshinyshiny-reactivity

解决方案


library(shiny)
library(DT)

callback <- c(
  "var colnames = table.columns().header().to$().map(function(){return this.innerHTML;}).get();",
  "Shiny.onInputChange('colnames', colnames);",
  "table.on('dblclick.dt', 'thead th', function(e) {",
  "  var $th = $(this);",
  "  var index = $th.index();",
  "  var colname = $th.text(), newcolname = colname;",
  "  var $input = $('<input type=\"text\">')",
  "  $input.val(colname);",
  "  $th.empty().append($input);",
  "  $input.on('change', function(){",
  "    newcolname = $input.val();",
  "    if(newcolname != colname){",
  "      $(table.column(index).header()).text(newcolname);",
  "      colnames[index] = newcolname;",
  "      Shiny.onInputChange('colnames', colnames);",
  "    }",
  "    $input.remove();",
  "  }).on('blur', function(){",
  "    $(table.column(index).header()).text(newcolname);",
  "    $input.remove();",
  "  });",
  "});"
)

ui <- fluidPage(
  verbatimTextOutput("colnames"),
  DTOutput("table")
)

server <- function(input, output){

  output$table <- renderDT({
    datatable(iris[1:3,], callback = JS(callback), 
              options = list(ordering = FALSE))
  }, server = FALSE) 

  output$colnames <- renderPrint({
    input$colnames                     
  })
}

shinyApp(ui, server)

推荐阅读