Shiny DT: Freeze rownames while sorting?
Asked Answered
D

1

6

I'm designing a Shiny app to rank people based on a variety of metics. Using the DT sorting feature, I want users to be able to click on any column and sort by it.

It seems natural to use the rownames as the rank; the problem is that these numbers sort along with the rest of the table. Is there any way to freeze this column so the rank numbers stay the same while the rest of the table sorts? Perhaps with a JavaScript function?

EDIT: In the example below, when I click "Metric_1," I want the rownames to stay 1, 2, 3, 4, instead of sorting to 3, 2, 1, 4 to match the new order of Person C, Person B, Person A, Person D. END EDIT

I don't see this option on the RStudio help page: https://rstudio.github.io/DT/

# Simplified example

library(shiny)
library(DT)


ui <- fluidPage(

    DT::dataTableOutput("table")

)

server <- function(input, output) {

    output$table <- DT::renderDataTable({

        x <- data.frame(
            Name = c("Person A", "Person B", "Person C", "Person D"), 
            Metric_1 = c(8, 7, 4, 10), 
            Metric_2 = c(3, 5, 2, 8)
        )

        datatable(x)

    })
}

shinyApp(ui = ui, server = server)
Damnedest answered 16/7, 2019 at 14:51 Comment(4)
Done - see above.Damnedest
I don't think there is default DT options to do this. There's a way to do it here... datatables.net/examples/api/counter_columns.htmlRiana
Thanks! That is exactly what I want. Now I'll see if I can figure out how to implement it...Damnedest
oooh, here's the R solution... #55115683Riana
R
5

Here's a working example using this SO answer

library(shiny)
library(DT)


ui <- fluidPage(

  DT::dataTableOutput("table")

)

server <- function(input, output) {
  js <- c(
    "table.on('draw.dt', function(){",
    "  var PageInfo = table.page.info();",
    "  table.column(0, {page: 'current'}).nodes().each(function(cell,i){", 
    "    cell.innerHTML = i + 1 + PageInfo.start;",
    "  });",
    "})")

  output$table <- DT::renderDataTable({

    x <- data.frame(
      Name = c("Person A", "Person B", "Person C", "Person D"), 
      Metric_1 = c(8, 7, 4, 10), 
      Metric_2 = c(3, 5, 2, 8)
    )

    datatable(x, callback = JS(js))

  })
}

shinyApp(ui = ui, server = server)
Riana answered 16/7, 2019 at 15:10 Comment(1)
Genius! Thanks for finding that, it works perfectly.Damnedest

© 2022 - 2024 — McMap. All rights reserved.