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.