1

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)
polkas
  • 3,797
  • 1
  • 12
  • 25
qwertzuiop
  • 172
  • 8

1 Answers1

1

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);
               });")
)
polkas
  • 3,797
  • 1
  • 12
  • 25
  • Thanks for the reply. I thought about conditional panel, but in most cases users are just using the add button. Do you happen to know how to use JS to open/closes this modal? – qwertzuiop Mar 16 '23 at 21:29