2

I'm trying to create a page to include and exclude boxes dynamically using boxDropdownItem from shinydashboardplus package, but the application is crashing, could someone help me please?

*Solutions using javascript are also welcome :)

Here my code:

shinyApp(
        ui = dashboardPage(
        dashboardHeader(),  
        dashboardSidebar(),
        dashboardBody(
        uiOutput("boxes")
        )
),

server = function(input, output) {

        rvs = reactiveValues(boxDropdownItem = list(), observers = list())

        output$boxes <- renderUI({
        for(i in 1:5) {
                rvs$boxDropdownItem[[i]] =
                column(width = 12,
                        box(    id = paste("box",i),
                                title = paste("box",i),
                                width = 4,
                                status = NULL,
                                dropdownMenu = boxDropdown(
                                        icon = icon("ellipsis-v"),
                                        boxDropdownItem(id = paste0("del",i), "Delete")
                                )
                        )
                )
        }

        rvs$observers = lapply(1:(length(rvs$boxDropdownItem)),function(i) {
  
        observeEvent(input[[paste0("del",i)]],{ 
                rvs$observers <- rvs$observers[-i]
                rvs$boxDropdownItem <- rvs$boxDropdownItem[-i]
        })
        }) 

        do.call(fluidRow, rvs$boxDropdownItem) 
})

}
)
  • 1
    If you'd like the user to be able to delete the boxes, you could add the argument `closable = T` in the `box` call in the `for` statement. It will add an `X` to the corner for closing the box. – Kat May 02 '21 at 13:21
  • Kat, thanks for your quick interaction. But in this case I really need to use the boxDropdownItem component instead of the box's x component. When the user clicks the delete option ("Remove"), I must delete the box dynamically. – Pereira Junior May 02 '21 at 17:31

1 Answers1

2

You need to first create the boxes as a reactiveValues object. Then you can control what you display in renderUI. I have shown here for 3 boxes. You can modify it to dynamic number. Try this

library(shinydashboardPlus)

shinyApp(
  ui = shinydashboard::dashboardPage(title = "My Box Dropdown",
    dashboardHeader(),  
    dashboardSidebar(),
    dashboardBody(
      uiOutput("boxes")
    )
  ),
  
  server = function(input, output) {
    
    rvs = reactiveValues(boxDropdownItem = list(), observers = list(), tmp=list())
    
    observe({
      for(i in 1:3) {
        rvs$boxDropdownItem[[i]] <-
          box(id = paste0("box",i),
              title = paste("box",i),
              width = 12,
              status = "warning",
              solidHeader = TRUE,
              collapsible = TRUE,
              dropdownMenu = boxDropdown(
                icon = icon("ellipsis-v"),
                boxDropdownItem("Click me", id = paste0("dropdownItem",i), icon = icon("heart")),
                dropdownDivider(),
                boxDropdownItem(id = paste0("del",i), "Delete")
              ),
              paste("My Box",i)
          )
        
      }
      
    })
    
    output$boxes <- renderUI({
      if (length(rvs$tmp)>0){
        rvs$boxDropdownItem[!(rvs$boxDropdownItem %in% rvs$tmp)]
      } else rvs$boxDropdownItem
    })
    
    lapply(1:3, function(i) {
      observeEvent(input[[paste0("del",i)]],{
        rvs$tmp[[i]] <<- rvs$boxDropdownItem[[i]]
      }, ignoreInit = TRUE)
      
      
      observeEvent(input[[paste0("dropdownItem",i)]], {
        showNotification("Hello", duration = i, type = "error")
      })

    })
    
  }
)

The picture below shows box 2 deleted.

output

YBS
  • 19,324
  • 2
  • 9
  • 27
  • How I do that? I would like to recognize your help. – Pereira Junior May 03 '21 at 13:07
  • At the top left of the answer, there is a number 0. Just above the number is a triangle pointing upwards, and if you hover over it, it state "this answer is useful". Click on that and the number 0 changes to 1. – YBS May 03 '21 at 13:11
  • When I try it, follow message appears: Thanks for the feedback! You need at least 15 reputation to cast a vote, but your feedback has been recorded. Excuse, I really happy with your answer, you helped me a lot. Let me know if there is another way to recognize you, please. – Pereira Junior May 03 '21 at 14:00
  • That is fine. You can wait until you gain 15 reputation points before you do it. I forgot about that requirement. – YBS May 03 '21 at 15:09