0

I am interested to have a data table as following in my shiny app. After I select the rows using the check boxes, I would like to continue working on the selected data. The problem now is that I don't know how to get the index of the selected rows from this example. Can you please help?

I want to extend the following code which is given by this answer.

library(shiny)
library(DT)
runApp(list(
    ui = fluidPage(dataTableOutput("dtout")),
    server = function(input, output, session) {
        shinyInput <- function(FUN, id, num, ...) {
            inputs <- character(num)
            for (i in seq_len(num)) {
                inputs[i] <- as.character(FUN(paste0(id, i), label = NULL, ...))
            }
            inputs
        }
        
        output$dtout <- renderDataTable({
            datatable(
                cbind(
                    Pick = shinyInput(
                        checkboxInput,
                        "srows_",
                        nrow(mtcars),
                        value = NULL,
                        width = 1
                    ),
                    mtcars
                ),
                options = list(
                    drawCallback = JS(
                        'function(settings) {Shiny.bindAll(this.api().table().node());}'
                    )
                ),
                selection = 'none',
                escape = F
            )
        }, server = FALSE)
    }
))

I think it has to do with the callback function. But I couldn't figure it out.

Jan
  • 2,245
  • 1
  • 2
  • 16
Wendy
  • 3
  • 1

1 Answers1

1

If you would like to get the row indices where the checkbox is clicked, you can define a function which gets the value per id of the inputs

shinyValue = function(id, len) {
    unlist(lapply(seq_len(len), function(i) {
        value = input[[paste0(id, i)]]
        if (is.null(value)) {
            NA
        }
        else {
            value
        }
    }))
}

and write these values into a data frame:

df <- data.frame(isChecked = shinyValue('srows_', nrow(mtcars)))

Then you get a list of these indices by using

which(df$isChecked == TRUE)

See this minimal example below:

enter image description here

library(shiny)
library(DT)

ui <- fluidPage(verbatimTextOutput("idxSelectedRows"),
                dataTableOutput("dtout"))

server <- function(input, output, session) {
    shinyInput <- function(FUN, id, num, ...) {
        inputs <- character(num)
        for (i in seq_len(num)) {
            inputs[i] <- as.character(FUN(paste0(id, i), label = NULL, ...))
        }
        inputs
    }
    
    shinyValue = function(id, len) {
        unlist(lapply(seq_len(len), function(i) {
            value = input[[paste0(id, i)]]
            if (is.null(value)) {
                NA
            }
            else {
                value
            }
        }))
    }
    
    output$idxSelectedRows <- renderPrint({
        df <- data.frame(isChecked = shinyValue('srows_', nrow(mtcars)))
        paste("Selected row indices: ",
              paste(which(df$isChecked == TRUE), collapse = ", "))
    })
    
    output$dtout <- renderDataTable({
        datatable(
            cbind(
                Pick = shinyInput(
                    checkboxInput,
                    "srows_",
                    nrow(mtcars),
                    value = NULL,
                    width = 1
                ),
                mtcars
            ),
            options = list(
                drawCallback = JS(
                    'function(settings) {Shiny.bindAll(this.api().table().node());}'
                )
            ),
            selection = 'none',
            escape = F
        ) 
    }, server = FALSE)
}

shinyApp(ui = ui, server = server)
Jan
  • 2,245
  • 1
  • 2
  • 16