代码之家  ›  专栏  ›  技术社区  ›  langtang

从tabsetPanel中动态删除所有导航面板

  •  1
  • langtang  · 技术社区  · 5 月前

    是否可以访问的名称 nav_panel() 导航容器中包含的对象。在下面的示例中,我想动态删除所有面板,如果我知道这些面板的名称,就可以这样做(请参见行 panel_names<-c("a", "b", "c") 。但是,在较大的应用程序中,这些面板是动态生成的,我可能不知道面板的名称

    library(shiny)
    library(bslib)
    library(purrr)
    
    ui <- fluidPage(
      
      actionButton("remove", "Remove all nav panels"),
      tabsetPanel(
        id="panel_set",
        nav_panel("a", "frame a"),
        nav_panel("b", "frame b"),
        nav_panel("c", "frame c")
      )
    )
    
    server <- function(input, output) {
      observe({
        panel_names = c("a", "b", "c") # How can I replace this line?
        walk(panel_names, \(pn) nav_remove("panel_set", target=pn))
      }) |> bindEvent(input$remove)
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    
    

    我该如何更换线路 panel_names<-c(“a”、“b”、“c”)

    1 回复  |  直到 5 月前
        1
  •  1
  •   Jan    5 月前

    htmltools 解决方案

    您可以使用 htmltools::tagQuery() :

    library(shiny)
    library(bslib)
    library(purrr)
    
    ui <- page_fluid(
      actionButton("remove", "Remove all nav panels"),
      tabsetPanel(
        id="panel_set",
        nav_panel("a", "frame a"),
        nav_panel("b", "frame b"),
        nav_panel("c", "frame c")
      )
    )
    
    server <- function(input, output, session) {
      
      observeEvent(input$remove, {
        panel_names <- sapply(
          htmltools::tagQuery(ui)$find("#panel_set")$find("a")$selectedTags(), 
          function(x){ tagGetAttribute(x, "data-value") }
        )
        walk(panel_names, \(pn) nav_remove("panel_set", target=pn))
      })
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    Javascript解决方案

    您可以使用 custom message handler 当点击按钮时,该功能被激活。它收集Javascript中的名字,并将其作为列表发送回Shiny。

    library(shiny)
    library(bslib)
    library(purrr)
    
    ui <- page_fluid(
      tags$head(
        tags$script("
          Shiny.addCustomMessageHandler('get_nav_panel_names', function(panel) {
            var names = $('#' + panel).find('a').map(function() {
              return $(this).attr('data-value');
            }).toArray();
            Shiny.setInputValue(panel + '_names', {names});
          });
        ")
      ),
      actionButton("remove", "Remove all nav panels"),
      tabsetPanel(
        id="panel_set",
        nav_panel("a", "frame a"),
        nav_panel("b", "frame b"),
        nav_panel("c", "frame c")
      )
    )
    
    server <- function(input, output, session) {
      
      observeEvent(input$remove, {
        session$sendCustomMessage("get_nav_panel_names", "panel_set")
        
        req(input$panel_set_names)
        panel_names <- unlist(unname(input$panel_set_names))
        walk(panel_names, \(pn) nav_remove("panel_set", target=pn))
      }, ignoreNULL = FALSE)
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    此处无关,但请注意,我替换了Shiny的 fluidPage 使用bslib page_fluid .