1

I have used a reactable with the option for select rows. But after filtering the reactable the row-numbers (respective the values) get from getReactableState("table", "selected") are wrong. Where is my mistake? By clicking on a row with unfiltered data, the row-numbers are correct. After filtering I get wrong values. How can I get the correct indexes of a filtered table?

library(shiny)
library(reactable)

data <- MASS::Cars93[, 1:7]

ui <- fluidPage(
  actionButton("select_btn", "Select rows"),
  selectInput("filter_type", "Filter type", unique(data$Type), multiple = TRUE),
  textInput("row", label = "Selected"),
  reactableOutput("table")
)

server <- function(session, input, output) {
  selected <- reactive(getReactableState("table", "selected"))
  
  output$table <- renderReactable({
    reactable(
      data,
      filterable = TRUE,
      searchable = TRUE,
      selection = "single",
    )
  })
  
  observeEvent(input$select_btn, {
    # Select rows
    updateReactable("table", selected = c(1, 3, 5))
  })

  observe({
    # Filter data
    filtered <- if (length(input$filter_type) > 0) {
      data[data$Type %in% input$filter_type, ]
    } else {
      data
    }
    updateReactable("table", data = filtered)
  })
  
  observe({
    updateTextInput(session, "row",  value = data$Model[selected()])
  })
  
  
}

shinyApp(ui, server)

1 Answers1

1

One possibility: Put your filtered data inside a reactive() and update the text input using data_filtered(). Similarly you can go on with the selected values.

enter image description here

library(shiny)
library(reactable)

data <- MASS::Cars93[, 1:7]

ui <- fluidPage(
    actionButton("select_btn", "Select rows"),
    selectInput("filter_type", "Filter type", unique(data$Type), multiple = TRUE),
    textInput("row", label = "Selected"),
    reactableOutput("table")
)

server <- function(session, input, output) {
    rv <- reactiveValues(data = data)
    
    data_filtered <- reactive({
        if (length(input$filter_type) > 0) {
            rv$data[rv$data$Type %in% input$filter_type,]
        } else {
            rv$data
        }
    })
    
    selected <- reactiveValues(j = 0)
    
    currentSelected <-
        reactive(getReactableState("table", "selected"))
    
    observeEvent(currentSelected(), priority = 0, {
        selected$j <- currentSelected()
    })
    
    output$table <- renderReactable({
        reactable(
            data_filtered(),
            filterable = TRUE,
            searchable = TRUE,
            selection = "single",
        )
    })
    
    observeEvent(input$select_btn, {
        # Select rows
        updateReactable("table", selected = c(1, 3, 5))
    })
    
    observe({
        if (is.null(getReactableState("table", "selected"))) {
            updateTextInput(session, "row", value = "")
        } else {
            updateTextInput(session, "row", value = data_filtered()$Model[selected$j])
        }
    })
    
}

shinyApp(ui, server)
Jan
  • 2,245
  • 1
  • 2
  • 16