Is there any way to sort a column in a table and the same column in another table? For example, in the code below I draw two datatables with mtcars data and I would like to sort the column mpg of the first table by clicking, showing the same sorting in the second table automatically, the same if I click on the second table, automatically sorting the first table.
library(DT)
library(shiny)
ui <- basicPage(
h2("The mtcars data"),
dataTableOutput("mytable"),
br(),
dataTableOutput("mytable2")
)
server <- function(input, output) {
output$mytable = DT::renderDataTable({
mtcars
})
output$mytable2 = DT::renderDataTable({
mtcars
})
}
shinyApp(ui, server)
I tried using stateSave
option with datatable
and believe this might be helpful. The order
option can be saved in reactiveValues
and be updated when the order of either table changes. Before changing the reactiveValues
, I make sure it is a change in order from what is stored, otherwise you may have duplicate updates of the datatable
. Finally, because the state would be saved in localStorage, adding stateDuration = -1
will prevent additional ordering when the user accesses the app again.
server <- function(input, output, session) {
rv <- reactiveValues(
options = list(stateSave = TRUE,
stateDuration = -1,
order = list())
)
output$mytable = DT::renderDataTable({
datatable(mtcars, options = rv$options)
})
output$mytable2 = DT::renderDataTable({
datatable(mtcars, options = rv$options)
})
observeEvent(input$mytable_state$order, {
if (!identical(rv$options$order, input$mytable_state$order)) {
rv$options$order <- input$mytable_state$order
}
})
observeEvent(input$mytable2_state$order, {
if (!identical(rv$options$order, input$mytable2_state$order)) {
rv$options$order <- input$mytable2_state$order
}
})
}
Edit: With regards to adding additional options, you would have different ways you could go about this.
First, you could add more options to rv
(e.g., add pageLength
):
rv <- reactiveValues(
options = list(stateSave = TRUE,
stateDuration = -1,
pageLength = 5,
order = list())
)
Alternatively, if you want to add the options
inside of datatable
, and maybe use different options between the two tables, you could instead store the order
in rv
:
server <- function(input, output, session) {
rv <- reactiveValues(
order = list()
)
output$mytable = DT::renderDataTable({
datatable(mtcars, options = list(
stateSave = TRUE,
stateDuration = -1,
order = rv$order))
})
output$mytable2 = DT::renderDataTable({
datatable(mtcars, options = list(
stateSave = TRUE,
stateDuration = -1,
order = rv$order))
})
observeEvent(input$mytable_state$order, {
if (!identical(rv$order, input$mytable_state$order)) {
rv$order <- input$mytable_state$order
}
})
observeEvent(input$mytable2_state$order, {
if (!identical(rv$order, input$mytable2_state$order)) {
rv$order <- input$mytable2_state$order
}
})
}
In this case, rv$order
will store the table order only, and not all of the options.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With