How could I remove/close multiple tabpanels at once in RShiny?

91 Views Asked by At

How could I remove/close multiple tabpanels at once? I make an RShiny apps where users can make queries. The queries will be shown in tabpanels. They can close one tabpanel or multiple tabpanels at once. But the code for the latter doesn't work. In this question I enclose the minimum code required to reproduce the problem. Many thanks in advance for your help.

library(shiny)

ui <- fluidPage(
    fluidRow(
        actionButton(inputId = "btnNewQuery",
                     label   = "New query"),
        actionButton(inputId = "btnCloseTabpanel",
                     label   = "Close tabpanel"),
        actionButton(inputId = "btnCloseAllTabpanels",
                     label   = "Close all tabpanels")
    ), 
    br(),
    fluidRow(
        tabsetPanel(id = "tabsetPanel_Queries", type = "tabs")
    )
)

server <- function(input, output, session){
    # Button: New query =====
    observeEvent(
        eventExpr = input$btnNewQuery, {
            showModal(
                modalDialog(
                    title = "Queryname",

                    textInput(
                    inputId = "txtQueryname",
                    label = "Queryname",
                    value = "",
                    width = "600px",
                    placeholder = "Fill in the queryname."),

                    footer = tagList(
                                 modalButton("Cancel"),
                                 actionButton(
                                     inputId = "btnQueryname_OK",
                                     label   = "OK")),
                    easyClose = TRUE
                ) #modalDialog
            ) #showModal
    }) 

    # Button: OK (of the messagebox) =====
    observeEvent(eventExpr = input$btnQueryname_OK, {
        removeModal()
        shiny::appendTab(
            inputId = "tabsetPanel_Queries",
            select  = TRUE,
            tabPanel(
                inputId = input$txtQueryname,
                title   = input$txtQueryname,
                value   = input$txtQueryname,
            ) #tabPanel
        ) #appendTab
    })
        
    # Button: Close tabpanel =====
    observeEvent(eventExpr = input$btnCloseTabpanel,{
        if(!is.null(input[["tabsetPanel_Queries"]])){
            shiny::removeTab(inputId = "tabsetPanel_Queries",
                         target  = input[["tabsetPanel_Queries"]])}
    })

    # Button: Close all tabpanels =====
    observeEvent(eventExpr = input$btnCloseAllTabpanels,{
        # This code doesn't work. It stays remain in a loop.
        while(!is.null(input[["tabsetPanel_Queries"]])){
            print(input[["tabsetPanel_Queries"]])
            shiny::removeTab(inputId = "tabsetPanel_Queries",
                             target  = input[["tabsetPanel_Queries"]])}
    })
}

shinyApp(ui, server)
1

There are 1 best solutions below

0
Gregory_SC On

The following codes work:

library(shiny)
library(tidyverse)
library(purrr)


ui <- fluidPage(
    fluidRow(
        actionButton(inputId = "btnNewQuery",
                     label   = "New query"),
        actionButton(inputId = "btnCloseTabpanel",
                     label   = "Close tabpanel"),
        actionButton(inputId = "btnCloseAllTabpanels",
                     label   = "Close all tabpanels")
    ), 
    br(),
    fluidRow(
        tabsetPanel(id = "tabsetPanel_Queries", type = "tabs")
    )
)


server <- function(input, output, session){
    tab_list <- NULL

    # Button: New query =====
    observeEvent(
        eventExpr = input$btnNewQuery, {
            showModal(
                modalDialog(
                    title = "Queryname",
                    textInput(
                        inputId     = "txtQueryname",
                        label       = "Queryname",
                        value       = "",
                        width       = "600px",
                        placeholder = "Fill in the queryname."),
                    footer = tagList(
                        modalButton("Cancel"),
                        actionButton(
                            inputId = "btnQueryname_OK",
                            label   = "OK")),
                    easyClose = TRUE
                ) #modalDialog
            ) #showModal
    })


    # Button: OK (of the messagebox) =====
    observeEvent(
        eventExpr = input$btnQueryname_OK, {
            removeModal()

            tab_title <- input$txtQueryname
    
            shiny::appendTab(
                inputId = "tabsetPanel_Queries",
                select  = TRUE,
                tabPanel(
                    inputId = input$txtQueryname,
                    title   = input$txtQueryname,
                    value   = input$txtQueryname,
                ) #tabPanel
            ) #appendTab
    
            tab_list <<- c(tab_list, tab_title)
    })


    # Button: Close tabpanel =====
    observeEvent(
        eventExpr = input$btnCloseTabpanel,{
            if(!is.null(input[["tabsetPanel_Queries"]])){
                shiny::removeTab(inputId = "tabsetPanel_Queries",
                                 target  = input[["tabsetPanel_Queries"]])}
    })


    # Button: Close all tabpanels =====
    observeEvent(
        eventExpr = input$btnCloseAllTabpanels,{
            print(tab_list)

            tab_list %>%
                walk(~removeTab("tabsetPanel_Queries", .x))

            tab_list <<- NULL
    })
}


shinyApp(ui, server)