8

I would like to highlight a row of a datatable in a Shiny app based on a marker clicked on a leaflet map. To do so I have to change the page and go to page 5 if row 46 is selected for example.

It works fine if I do not change the rows order.

enter image description here

If I reorder the rows (for example on ascending val), I cannot find a way to go to the page corresponding to the selected row.

I have ckecked the dataTableProxy manual but it has not helped.

Any help would be much appreciated.

A code example you can run:

ui.R

library(shiny)
library(leaflet)
library(DT)

shinyUI(fluidPage(
  mainPanel(
    leafletOutput("Map"),
    dataTableOutput("Table")
  )
))

server.R

library(shiny)
library(leaflet)
library(DT)

shinyServer(function(input, output) {

  nbpts <- 50
  center <- c(47,3)
  ref <- 1:nbpts
  lat <- rnorm(nbpts, center[1], 2)
  lng <- rnorm(nbpts, center[2], 2)
  val <- sin(lat+lng)

  data <- data.frame(ref, lat, lng,val)

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

  TableProxy <-  dataTableProxy("Table")

  output$Map <- renderLeaflet({
    data_map <- leaflet(data) %>%
      addTiles() %>%
      addCircleMarkers(
        lng=~lng,
        lat=~lat,
        layerId = ~ref,
        radius = 4,
        color = "purple",
        stroke = FALSE,
        fillOpacity = 0.5
      )
    data_map
  })

  observeEvent(input$Map_marker_click, {
    clickId <- input$Map_marker_click$id
    dataId <- which(data$ref == clickId)
    TableProxy %>%
      selectRows(dataId) %>%
      selectPage(dataId %/% 10 + 1)
  })
})
vwrobel
  • 1,706
  • 15
  • 25

1 Answers1

8

It seems that for the rows you should filter for the ref number and the page number you should calculate with the help of the actual row number.

This should help you:

  observeEvent(input$Map_marker_click, {
      clickId <- input$Map_marker_click$id
      dataTableProxy("Table") %>%
      selectRows(which(data$ref == clickId)) %>%
      selectPage(which(input$Table_rows_all == clickId) %/% 10 + 1)
  })

Upvote, because the question was quite interesting.

Edit: Credits to NicE for the hint for the dynamic table length variable, see the comments.

   output$Table <- renderDataTable({
       DT::datatable(data, selection = "single",options=list(stateSave = TRUE))
   })

   observeEvent(input$Map_marker_click, {
      clickId <- input$Map_marker_click$id
      dataTableProxy("Table") %>%
      selectRows(which(data$ref == clickId)) %>%
      selectPage(which(input$Table_rows_all == clickId) %/% input$Table_state$length + 1)
  })
Tonio Liebrand
  • 17,189
  • 4
  • 39
  • 59
  • 3
    You could also replace the `10` (rows per page) by `input$Table_state$length` to make this responsive to users changing that parameter. (This requires `stateSave=TRUE` in the datatable call, `DT::datatable(data, selection = "single",options=list(stateSave = TRUE))` ) – NicE Apr 28 '17 at 12:51