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

R Shiny:Datatable双击触发模态框无法显示响应式值问题

问题原因

你遇到的核心问题是:双击事件仅自定义了dt_dblclick输入信号,但没有触发DT组件的行选中状态更新,导致input$test_rows_selected始终保持之前的选中值(初始为空),模态框内容依赖这个无效值自然无法正确显示。而改用input$test_rows_selected触发时,这个输入本身已经同步了行选中状态,所以能拿到正确数据。

另外注意你代码里的一个笔误:模态框中"Petal Width"对应的是iris$Species,这明显错误,应该改为iris$Petal.Width。

解决方案

有两种可行的修复方式,任选其一即可:

方式一:双击时同步选中该行

修改DT的JS回调,在发送自定义输入前先选中当前行,让input$test_rows_selected同步更新:

ui <- fluidPage(DT::dataTableOutput("test"))

server <- function(input, output, session) {
  
  output$test <- DT::renderDataTable({
    DT::datatable(
      data = iris, 
      class = 'compact',
      escape = FALSE,
      rownames = FALSE,
      selection = "single",
      options = list(
        dom = "t",
        ordering = FALSE,
        paging = FALSE,
        autoWidth = FALSE,
        scrollY = "100vh",
        scrollCollapse = FALSE
      ),
      callback = htmlwidgets::JS(
        "table.on('dblclick', 'td',", 
        "  function() {",
        "    var row = table.cell(this).index().row;",
        "    table.row(row).select(); // 新增:选中当前行",
        "    var col = table.cell(this).index().column;",
        "    Shiny.setInputValue('dt_dblclick', {dt_row: row, dt_col: col});",
        "  }",
        ");"
      )
    ) 
  }, server = FALSE)
  
  modal_content <- reactive(paste(
    '<figure class="snip0056 yellow">
    <figcaption>
      <h5 style="color:black;font-size:3rem"><b> Flower name:', iris$Species[input$test_rows_selected], '</b></h5>
      <h2 style="color:#7C8386;font-size:2.5rem"><b> Petal Width:', iris$Petal.Width[input$test_rows_selected], '</b></h2> <!-- 修正笔误 -->
    <h5 style="color:#3ba51a;font-size:2rem;padding-top: 10px;">Keywords: </b></h5></i>',
    checkboxGroupButtons(
      inputId = "domaines_tags",
      label = "",
      choices = c(unique(iris$Species[input$test_rows_selected])),
      selected = NULL
    ),
    '<div class="icons"><a href="#"><i class="ion-ios-home"></i></a><a href="#"><i class="ion-ios-email"></i></a><a href="#"><i class="ion-ios-telephone"></i></a></div>
    </figcaption><img src="https://u.cubeupload.com/adsuri/7NQDHz.jpeg" alt="sample9" width="10"/></figure>'))
  
  observeEvent(input$dt_dblclick, {
    showModal(modalDialog(
      title = "Popup test",
      HTML(modal_content()),
      footer = tagList(
        modalButton("Annuler")
      ),  size = "l"
    ))
  })
}

shinyApp(ui, server)

方式二:直接使用双击事件的行索引获取数据

不再依赖input$test_rows_selected,而是用input$dt_dblclick中的行号(注意JS返回的是0-based索引,需要转成R的1-based索引):

ui <- fluidPage(DT::dataTableOutput("test"))

server <- function(input, output, session) {
  
  output$test <- DT::renderDataTable({
    DT::datatable(
      data = iris, 
      class = 'compact',
      escape = FALSE,
      rownames = FALSE,
      selection = "single",
      options = list(
        dom = "t",
        ordering = FALSE,
        paging = FALSE,
        autoWidth = FALSE,
        scrollY = "100vh",
        scrollCollapse = FALSE
      ),
      callback = htmlwidgets::JS(
        "table.on('dblclick', 'td',", 
        "  function() {",
        "    var row = table.cell(this).index().row;",
        "    var col = table.cell(this).index().column;",
        "    Shiny.setInputValue('dt_dblclick', {dt_row: row, dt_col: col});",
        "  }",
        ");"
      )
    ) 
  }, server = FALSE)
  
  modal_content <- reactive({
    req(input$dt_dblclick) # 确保输入存在
    row_idx <- input$dt_dblclick$dt_row + 1 # 转成1-based索引
    paste(
      '<figure class="snip0056 yellow">
      <figcaption>
        <h5 style="color:black;font-size:3rem"><b> Flower name:', iris$Species[row_idx], '</b></h5>
        <h2 style="color:#7C8386;font-size:2.5rem"><b> Petal Width:', iris$Petal.Width[row_idx], '</b></h2> <!-- 修正笔误 -->
      <h5 style="color:#3ba51a;font-size:2rem;padding-top: 10px;">Keywords: </b></h5></i>',
      checkboxGroupButtons(
        inputId = "domaines_tags",
        label = "",
        choices = unique(iris$Species[row_idx]),
        selected = NULL
      ),
      '<div class="icons"><a href="#"><i class="ion-ios-home"></i></a><a href="#"><i class="ion-ios-email"></i></a><a href="#"><i class="ion-ios-telephone"></i></a></div>
      </figcaption><img src="https://u.cubeupload.com/adsuri/7NQDHz.jpeg" alt="sample9" width="10"/></figure>'
    )
  })
  
  observeEvent(input$dt_dblclick, {
    showModal(modalDialog(
      title = "Popup test",
      HTML(modal_content()),
      footer = tagList(
        modalButton("Annuler")
      ),  size = "l"
    ))
  })
}

shinyApp(ui, server)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:20:32