r shiny how to combine data table proxy and bs modal

75 views Asked by At

I would like to display selected items from a table. The table is displayed via bsModal. And the selection of the table is done via dataTableProxy. I would also like to be able to select certain items via a button.

Problem: If I start the app and click on the "add" button, nothing happens. I have to open the Modal first (I don't have to select anything) for the button to work. Only once the modal has been opened once, I can use the button.

library(shiny)
library(shinyBS)
library(DT)
library(dplyr)

ui <- fluidPage(
  actionButton("search", "Search for Items"),
  actionButton("add_items", "Add Items"),
  DTOutput("selection"),
  
  bsModal("modal", "DT", "search", DTOutput("data"))
)

server <- function(input, output) {
  output$data <- renderDT({
    datatable(iris)
  })
  
  shortlist_dt <- reactive({
    if(is.null(input$data_rows_selected)){return()}
    datatable(iris %>% slice(input$data_rows_selected))
    })
  
  output$selection <- renderDT(shortlist_dt())
  
  proxy_data = dataTableProxy('data')
  
  observeEvent(input$add_items, {
    proxy_data %>% selectRows(c(input$data_rows_selected, 2, 3))
  })
}

shinyApp(ui, server)
1

There are 1 answers

1
polkas On

The problem comes from the fact that the data output object is not yet rendered when the app is initialized. The moment when you open the modal is the moment when the output is indeed materialized.

Possible solutions:

  • (Applied) conditionalPanel for the insert button so sb has to start with the search step
  • Java Script code to open and close the modal when the app is started
  • Redesign the app
  • ...
library(shiny)
library(shinyBS)
library(DT)
library(dplyr)

ui <- fluidPage(
  tags$span(  
    style = "display: flex",
    actionButton("search", "Search for Items"),
    conditionalPanel("output.data", actionButton("add_items", "Add Items"))
  ),
  DTOutput("selection"),
  bsModal("modal", "DT", "search", DTOutput("data"))
)

server <- function(input, output) {
  output$data <- renderDT({
    datatable(iris)
  })
  
  shortlist_dt <- reactive({
    if(is.null(input$data_rows_selected)){return()}
    datatable(iris %>% slice(input$data_rows_selected))
  })
  
  output$selection <- renderDT(shortlist_dt())
  
  proxy_data = dataTableProxy('data')
  
  observeEvent(input$add_items, {
    proxy_data %>% selectRows(c(input$data_rows_selected, 2, 3))
  })
}

shinyApp(ui, server)

EDIT:

Code for clicking and closing the modal when the app started.

ui <- fluidPage(
  actionButton("search", "Search for Items"),
  actionButton("add_items", "Add Items"),
  DTOutput("selection"),
  bsModal("modal", "DT", "search", DTOutput("data")),
  tags$script("$(document).on('shiny:connected', function() {
                 $('button#search').click();
                 setTimeout(function() {
                   $('div.modal-footer button').click();
                 }, 1000);
               });")
)