I'm trying to use the reactable
package to hop to a specific row index after a user modifies the data underlying the reactable
.
library(shiny)
library(reactable)
library(dplyr)
ui <- fluidPage(
selectInput("index", "Index", choices = seq_len(nrow(iris))),
selectInput("species", "Species", choices = unique(iris$Species)),
actionButton("go", "Modify"),
reactableOutput("table")
)
server <- function(input, output, session) {
# Reactive data
data <- reactiveValues(
data = iris |> mutate(Index = row_number())
)
# Render reactable
output$table <- renderReactable({
reactable(data$data)
})
# Update data on button click
observeEvent(
input$go,
{
# modify the one record
x <- data$data |>
filter(Index == input$index) |>
mutate(Species = input$species)
# rm from all data
data$data <- data$data |>
filter(Index != input$index) |>
bind_rows(x) |>
arrange(Index)
# get index of change
index <- x |> pull(Index)
# hop to that approximate page
updateReactable("table", page = ceiling(index / 10))
}
)
}
shinyApp(ui, server)
The observeEvent()
successfully updates the data but does not hop to the page of the modified index. I.e., if a user is on page 1 but modifies the record with Index == 44
from setosa
to versicolor
, I'd like to use reactable::updateReactable()
to jump to that page. When running this code, it looks like it tries to jump to the page before the reactable
output renders the new data, which is what I'm assuming the issue is.
isolate()
will work in this case, but can cause issues if something in the table requires rendering on each update (i.e., an icon). See this follow-up SO question.
library(shiny)
library(reactable)
library(dplyr)
ui <- fluidPage(
actionButton("go", "Add Observation"),
reactableOutput("table")
)
server <- function(input, output, session) {
# Reactive data
data <- reactiveValues(
data = iris |> mutate(Index = row_number()),
tbl_page = 1
)
# Render reactable, but isolate
output$table <- renderReactable({
data$data |>
reactable() |>
htmlwidgets::onRender(
"function(el, x) {
Shiny.setInputValue('tbl_rendered', Date.now())
}"
)
})
# Update data on button click
observeEvent(
input$go,
{
# create a record to add
x <- data$data |>
dplyr::slice_sample(n = 1) |>
dplyr::mutate(Index = nrow(data$data) + 1)
# add a record and re id
data$data <- bind_rows(
data$data,
x
) |>
dplyr::arrange(Index)
# get index of change, save the needed page
index <- tail(data$data, 1) |> dplyr::pull(Index)
# update reactiveVals
data$tbl_page <- ceiling(index / 10)
}
)
# jump to page after table has rendered
shiny::observeEvent(
input$tbl_rendered,
reactable::updateReactable("table", page = data$tbl_page)
)
}
shinyApp(ui, server)