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

如何在reactable表格中通过双击事件触发模态窗口

Reactable单元格双击触发模态窗口并获取行索引解决方案

问题需求

我希望在reactable表格的单元格上触发双击事件以打开模态窗口,同时需要获取行索引,以便在模态窗口中显示对应行的图片。

现有代码可实现双击最后一列时弹出window.alert,但我更擅长用R编写代码,想要实现功能更丰富的模态窗口:

library(shiny)
library(tidyverse)
library(reactable)

ui <- fluidPage(
  fluidRow(
    column(12, align = 'center',reactableOutput("tbl"))
  )
)
server <- function(input, output, session) {
  
  data = reactive({mtcars %>% tibble::rownames_to_column('car')})
  
  output$tbl = renderReactable(
    reactable(
      data(),
      columns = list(
        carb = colDef(
          sticky = "right",
          sortable = FALSE,
          cell = function(value, index, name){
            icon("globe",
                 ondblclick = sprintf("window.alert('double clicked cell %s in column %s')", index, name)
            )
          })
      ),
      compact = T,
      highlight = T,
      onClick = JS("      function(rowInfo, colInfo, column) {
        if (colInfo.id !== 'carb') {
          Shiny.setInputValue('qwert', {id:rowInfo.id, nonce:Math.random()});
        }
      }"),
      rowStyle = list(cursor = "pointer")
    )
  )
  
  observeEvent(input$qwert, {
    print(input$qwert)
    id <- input$qwert$id
    row_nr <- as.numeric(id)+1
    showModal(
      modalDialog(
        size = 'l',
        easyClose = T,
        title = data()$car[row_nr],
        "some text"
      )
    )
  })
  
   observeEvent(input$poiu, {
     print(input$poiu)
     id2 <- input$poiu$id
     row_nr2 <- as.numeric(id2)+1
     showModal(
       modalDialog(
         title = data()$car[row_nr2],
         "double click"
       )
     )
   })

}
shinyApp(ui = ui, server = server)

我尝试了以下几种写法,均未成功:

  • sprintf(Shiny.setInputValue('poiu', {nonce:Math.random()})):仅尝试触发模态窗口
  • ondblclick = sprintf(Shiny.setInputValue('poiu', {id:%s.id, nonce:Math.random()}), index)
  • cell = function(value, index){ icon("globe", ondblclick = shinyjs::runjs(paste0("shiny.setInputValue('poiu',", index)) )}

解决方案

修正后的完整代码

library(shiny)
library(tidyverse)
library(reactable)

ui <- fluidPage(
  fluidRow(
    column(12, align = 'center', reactableOutput("tbl"))
  )
)
server <- function(input, output, session) {
  
  data = reactive({mtcars %>% tibble::rownames_to_column('car')})
  
  output$tbl = renderReactable(
    reactable(
      data(),
      columns = list(
        carb = colDef(
          sticky = "right",
          sortable = FALSE,
          cell = function(value, index, name){
            # 关键修正:正确生成双击触发的JS代码,传递行索引到Shiny输入
            icon("globe",
                 ondblclick = sprintf(
                   "Shiny.setInputValue('poiu', {id: '%s', nonce: Math.random()})", 
                   index
                 )
            )
          })
      ),
      compact = T,
      highlight = T,
      onClick = JS("      function(rowInfo, colInfo, column) {
        if (colInfo.id !== 'carb') {
          Shiny.setInputValue('qwert', {id:rowInfo.id, nonce:Math.random()});
        }
      }"),
      rowStyle = list(cursor = "pointer")
    )
  )
  
  observeEvent(input$qwert, {
    print(input$qwert)
    id <- input$qwert$id
    row_nr <- as.numeric(id)+1
    showModal(
      modalDialog(
        size = 'l',
        easyClose = T,
        title = data()$car[row_nr],
        "some text"
      )
    )
  })
  
  observeEvent(input$poiu, {
    print(input$poiu)
    id2 <- input$poiu$id
    # 注意:reactable的index从1开始,无需+1
    row_nr2 <- as.numeric(id2)
    showModal(
      modalDialog(
        size = 'l',
        easyClose = T,
        title = data()$car[row_nr2],
        # 这里可以替换为对应行的图片,比如:img(src = data()$image_url[row_nr2])
        paste0("这是第", row_nr2, "行的内容")
      )
    )
  })

}
shinyApp(ui = ui, server = server)

关键修改说明

  1. 双击事件的JS代码生成:
    在cell函数中,通过sprintf正确拼接JavaScript代码,将index(行索引,从1开始)作为字符串传递给Shiny.setInputValue,同时添加nonce: Math.random()确保Shiny能检测到输入值的变化(避免重复点击不触发事件)。
  2. 行索引的处理:
    reactable的index参数本身就是从1开始的行号,因此在observeEvent(input$poiu)中无需再加1,直接转换为数值即可获取对应行。
  3. 模态窗口内容扩展:
    可以在模态窗口中直接添加图片元素,比如img(src = data()$image_column[row_nr2]),只需将data()中的对应图片列替换为实际的图片URL列即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 00:17:46