简体   繁体   中英

Shiny modules: how to access selected_rows with DT::datatables?

When using shiny modules and DT::datatable I would like to access the selected_rows server-side. If my DT:datatable ID is my_DT_table then I would expect that the object input$my_DT_table_selected_rows contains the index of the selected row. This works perfectly well in shiny applications without modules.

However, if I use modules then this approach no longer works and the input object input$my_DT_table_selected_rows no longer contains the index of the selected row.

When working with DT:datatable function we can use built-in functionality to learn about selected rows in the UI.

The object: input$my_DT_table_rows_selected contains the index of the selected row where my_DT_table is the ID of the DT::datatable.

However, when working with modules, the name of the table is now different. It has a prefix which is equal to the ID used to call the module's UI function. So if that ID is my_ID then the table name will become: my_ID-table_name (note the hyphen after the ID). This can be easily verified using the developer tools in your browser (eg inspector in FireFox). And the associated input object name then becomes (and we need back ticks to prevent R from interpreting the hyphen as a minus sign):

input$`my_ID-table_name_rows_selected`

Here is a very basic example with some additional learning regarding how to pass a reactive object to a module. The reactive object contains the index of the selected line. I need to pass it without parenthesis. Inside of the module_server function I refer to the reactive object with parenthesis.

UI module in ui_module.R

module_ui <- function(id) {
  ns <- NS(id) # create namespace

  tagList(
    fluidRow(column(6, DT::dataTableOutput(ns("dt_table")))),
    fluidRow(column(4, verbatimTextOutput(ns("render_selected_line"))))
  )
}

Server module in server_module.R

table_server <- function(input, output, session, data) {

  output$dt_table <- DT::renderDataTable(
    DT::datatable(
    data = data,
    selection = "single"
    )
  )
}

selected_line_server <- function(input, output, session, data) { 
  output$render_selected_line <- renderText({
    paste0("My selection was: ", data()) # refer to the reactive object with parenthesis
  })

}

Shiny application

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

source("./modules/ui_module.R")
source("./modules/server_module.R")

ui <- fluidPage(
  module_ui("my_ID")
)

server = function(input, output, session) {
  data <- mtcars
  callModule(table_server, id = "my_ID", data = data) # data is not reactive
  callModule(selected_line_server, id = "my_ID", data = selectedLine) # refer to the reactive object selectedLine without parenthesis

  selectedLine <- reactive({
    req(input$`my_ID-dt_table_rows_selected`)
    if (is.null(input$`my_ID-dt_table_rows_selected`)) {
      return(NULL)
    } else {
      rows_selected <- as.numeric(input$`my_ID-dt_table_rows_selected`) # we need to prefix dt_table_rows_selected with the ID of the UI function "my_ID" and a hyphen
    }
  })

}

shinyApp(ui = ui, server = server)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM