I am running into an issue with datatables and shiny, specifically within a flexdashboard but I think that is irrelevant.
I want to scroll to a given row in the datatable when I click on the corresponding point in a plot. But, the minimal problem I have is to 'simply' scroll to any row. I can select a row using JavaScript with the option initComplete but scrollTo() will not do anything for me.
Looking at a previous question, Scroll to specific row in Datatable API, I got to this example, https://codepen.io/anon/pen/KWmpjj. It showcases the javascript function you could use with initComplete , but this was not made with R/Shiny. Specifically you'll find the following option for a small datatable:
initComplete: function () {
this.api().row(14).scrollTo();
$(this.api().row(14).node()).addClass('selected');
}
Since my goal is to use this in a flexdashboard I have a minimal example in R markdown format. A pretty standard call to DT::renderDataTable
with random data. I don't understand why this.api().table().row(15).scrollTo();
will not do anything. I added an alert to confirm that the JavaScript of initComplete
actually ran.
---
title: "Scroll to row in datatable"
date: "20 december 2017"
output: html_document
runtime: shiny
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Datatable automatically scroll to given row
The goal is to have a datatable rendered in a flexdashboard. Upon selecting a point in a scatter plot, the corresponding row in the table gets selected and needs to be scrolled into view. Selecting a row by clicking a point in a plot (with ggplot) works, but scrolling will not.
Preferably without using shinyApp(), since scrolling is a JavaScript functionality rather than a shiny one (?).
```{r}
library(dplyr)
library(DT)
# Generate random data
df <- data.frame(matrix(runif(1000), ncol = 5))
# Render datatable with shiny
DT::renderDataTable({
DT::datatable(df,
extensions = 'Scroller',
# selection = 'single', # Eventually only allow single selection
escape = FALSE,
# callback = JS('this.api().row(15).scrollTo();'), # Attempt to use callback instead
options = list(scrollX = TRUE,
scrollY = 200,
paging = FALSE,
initComplete = JS('function() {
$(this.api().table().row(15).node()).addClass("selected");
this.api().table().row(15).scrollTo();
alert("scrolled");}')))},
server = TRUE) # Setting server = TRUE results in the selection with initComplete breaking
```
What I have noticed is that if you scroll the table in the previously linked example the text at the bottom will actually update and say "Showing 1 to 6 of 20 entries" or "Showing 6 to 11 of 20 entries", etc. This does not happen in my example datatable, that always says Showing 1 to 200 of 200 entries. That leads me to think that it does not scroll to the specified row because everything is already 'in view', even though it is not really.
You need to set
scroller = TRUE
andpaging = TRUE
in thedatatable()
options
argument. This is working for me: