2

Basically, I want the output DataTable to switch to the page that has the values matching with the Input selection value (radioButtons). I know I can do a simple filter but that would remove all the other rows that do not match the criteria which I do not want.

Any help is appreciated! Thanks!

library(shiny)
library(DT)

ui <- basicPage(
  h3("The mtcars data"),
  fluidRow(column(2,
                  offset = 1,
                  radioButtons("valSel", strong("Gear"),
                               inline = TRUE,
                               choices = c("3", "4", "5"),
                               selected = "3")),
           fluidRow(column(10,
                           offset = 1,
                           dataTableOutput("mytable")))
  )
)

server <- function(input, output) {
  
  output$mytable = DT::renderDataTable({
    mtcars[mtcars$gear == input$valSel, ]
  })
}

shinyApp(ui, server)

Created on 2021-05-27 by the reprex package (v2.0.0)

Tung
  • 26,371
  • 7
  • 91
  • 115
  • 2
    I'm not sure how would that work. The datatable shows 10 entries, but this number does not match the number of cases in each value of gear. However, this Q&A has an application somewhat similar to your issue. https://stackoverflow.com/questions/56807006/shiny-dt-how-to-type-page-number-manually – David Jorquera May 27 '21 at 18:57

2 Answers2

2

You can create a custom js function and switch to the desired page. Try this

library(shiny)
library(DT)
library(tidyverse)

ui <- basicPage(
  h3("The mtcars data"),
  fluidRow(column(2,
                  offset = 1,
                  radioButtons("valSel", strong("Gear"),
                               inline = TRUE,
                               choices = c("3", "4", "5"),
                               selected = "3")),
           fluidRow(column(10,
                           offset = 1, # verbatimTextOutput("t1"),
                           DTOutput("mytable")))
  ),
  tags$script(HTML(
    "Shiny.addCustomMessageHandler('pager',function(page) {
      $('#'+'mytable').find('table').DataTable().page(page).draw(false);
    })"
  ))
)

server <- function(input, output, session) {

  mydf <- reactive({
    mtcars %>% mutate(rowid = row_number())
  })

  subdf <- reactive({
    req(mydf())
    mydf()[mydf()$gear == input$valSel, ]
  })
  output$t1 <- renderPrint({ceiling(min(subdf()$rowid)/10)})

  output$mytable = renderDT({
    n <- length(names(mydf())) ## to remove rowid
    mydf()[,-n]
  })

  observeEvent(input$valSel,{

    page <- ceiling(min(subdf()$rowid)/10) ## assumes 10 rows are displayed per page (default); if different, replace 10 by the number of rows displayed per page
    
    session$sendCustomMessage("pager",page-1)

  })

}

shinyApp(ui, server)
YBS
  • 19,324
  • 2
  • 9
  • 27
1

It isn't clear how you would identify the page where particular values are given they may contain different numbers of rows.

One alternative to setting the page would be to use the factor data type to reorder the categories depending on the radio button input, which would simply bring the category of interest to the top of the data frame being passed to renderDatatable:

library(shiny)
library(DT)

ui <- basicPage(
  h3("The mtcars data"),
  fluidRow(column(2,
                  offset = 1,
                  radioButtons("valSel", strong("Gear"),
                               inline = TRUE,
                               choices = c("3", "4", "5"),
                               selected = "3")),
           fluidRow(column(10,
                           offset = 1,
                           dataTableOutput("mytable")))
  )
)

server <- function(input, output) {
  
  df <- reactive({
    gear_vals <- unique(as.character(mtcars$gear))
    mtcars$gear <- factor(mtcars$gear, 
                          levels = c(input$valSel, 
                                     gear_vals[input$valSel != gear_vals]))
    mtcars[order(mtcars$gear),]
  })
  
  output$mytable = DT::renderDataTable({
    df()
  })
}

shinyApp(ui, server)
henryn
  • 1,163
  • 4
  • 15
  • Thanks! My reasoning was that: we might know the page number for each `gear` in advance (not sure if it's possible with `DT`). So before any selection takes place, reset the table back to its original form, then go to that page. – Tung May 28 '21 at 18:13