0

I have the shiny app below in which I click on datatable row and display its index next to it. Is it possible to press the Next button and display the index of the next row? The table's next row will be highlighted accordingly everytime as well.

library(shiny)
library(DT)


shinyApp(
  ui = fluidPage(
    title = 'Select Table Rows',
    
    h1('A Server-side Table'),
    
    fluidRow(
      column(9, DT::dataTableOutput('x3')),
      column(3, verbatimTextOutput('x4')),
      actionButton("next","Next row")
    )
    
  ),
  server = function(input, output, session) {

    # server-side processing
    mtcars2 = mtcars[, 1:8]
    output$x3 = DT::renderDataTable({datatable(selection = list(target = "row", mode = "single"),mtcars2 )})
    
    # print the selected indices
    output$x4 = renderPrint({
      s = input$x3_rows_selected
      if (length(s)) {
        cat('These rows were selected:\n\n')
        cat(s, sep = ', ')
      }
    })
})
firmo23
  • 7,490
  • 2
  • 38
  • 114
  • It should be possible with the **Select** extension, but this requires to set `server = FALSE`. – Stéphane Laurent Jan 15 '21 at 03:07
  • Can this be done? I try to combine it with your method here https://stackoverflow.com/questions/65712967/move-to-the-next-row-of-clicked-one-in-a-dt-datatable-using-an-actionbutton – firmo23 Jan 15 '21 at 03:11

1 Answers1

1
library(shiny)
library(DT)

dat <- iris[1:6,]

callback <- JS(
  "$('#btn-next').prop('disabled', true);",
  "var selected_row = null;",
  "table.on('select', function( e, dt, type, indexes ) {",
  "  $('#btn-next').prop('disabled', false);",
  "  selected_row = indexes[0];",
  "});",
  "table.on('deselect', function( e, dt, type, indexes ) {",
  "  $('#btn-next').prop('disabled', true);",
  "});",
  "var nrows = table.rows().count();",
  "$('#btn-next').on('click', function() {",
  "  var next_row = selected_row + 1 < nrows ? selected_row + 1 : 0;",
  "  table.row(next_row).select();",
  "});"
)

ui <- fluidPage(
  br(),
  DTOutput("dtable"),
  br(),
  splitLayout(
    textOutput("selectedRow"),
    actionButton("btn-next", "select next row"),
    cellWidths = "150px"
  )
)

server <- function(input, output, session) {
  
  output[["dtable"]] <- renderDT({
    datatable(
      dat, 
      extensions = "Select",
      selection = "none",
      callback = callback,
      options = list(
        columnDefs = list(
          list(className = "dt-center", targets = "_all")
        ),
        select = list(style = "single")
      )
    )
  }, server = FALSE)
  
  output[["selectedRow"]] <- renderText({
    i <- input[["dtable_rows_selected"]]
    paste0(
      "Selected row: ", 
      ifelse(is.null(i), "none", i)
    )
  })
  
}


shinyApp(ui, server)
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • cool that worked fot the other Q as well thanks a lot you re magician. I have posted a similar one with a shiny widget instead of actionbutton() https://stackoverflow.com/questions/65729967/select-specific-row-of-a-datatable-with-a-shiny-widget – firmo23 Jan 15 '21 at 04:39
  • as I understand callback is the key. Can it be combined with a shiny widget except of the actionbutton btn-next? – firmo23 Jan 15 '21 at 13:59