R Shiny - 使用 renderUI 动态添加 tabPanel 到 tabsetPanel

50

我正在开发一个闪亮的应用程序,其中我使用tabsetPanel,当用户输入特定内容时生成。因此,我想使用renderUI函数使一个选项卡面板出现/消失。

我的难点是tabsetPanel元素(tabsetPanel的参数)的数量也取决于用户的输入,这样有时我只需要一个,而其他时候我想要更多的tabPanels

如何做到呢?我尝试在tabsetPanel参数中包含conditionPanel或包含简单的if()...条件,但是它(不出所料...)没有起作用。

2个回答

85

请看这里。代码相当易懂。

library(shiny)
runApp(list(
  ui = pageWithSidebar(
    headerPanel('Dynamic Tabs'),
    sidebarPanel(
      numericInput("nTabs", 'No. of Tabs', 5)
    ),
    mainPanel(
      uiOutput('mytabs')  
    )
  ),
  server = function(input, output, session){
    output$mytabs = renderUI({
      nTabs = input$nTabs
      myTabs = lapply(paste('Tab', 1: nTabs), tabPanel)
      do.call(tabsetPanel, myTabs)
    })
  }
))

很高兴能够帮助您。如果您对代码本身有任何疑问,请在此处发布。 - Ramnath
附加说明:当您添加了选项卡之后,如何以正确的方式将相同的“uiOutput”添加到所有选项卡中,但使每个选项卡内的值保持唯一?还是说这不同?如果您添加一个“output$base_tab_ui”,并在每个选项卡中进行渲染,则它们都会为每个选项卡保留相同的“input$value”。有没有办法使用不同的输入变量名称使它们保持唯一? - Jenks
@Ramnath 你会如何填充这些动态标签页中的每个标签页自己的内容?比如说,一个数据框的renderTable / tableOutput,可以使用同样的对象进行筛选,该对象用于填充标签名称(即 nTabs = length(lags_7)my Tabs = lapply(sprintf('%s', lags_7), tabPanel))(可能的答案在此处:https://dev59.com/m1kS5IYBdhLWcg3w8aYL) - d8aninja
假设您已经将一些图形添加到名为myPlots的列表中,您可以执行以下操作:nTabs = length(myPlots); myTabs = lapply(1:nTabs, function(x){tabPanel(paste0("Tab ",x), renderPlot(myPlots[[x]]))}); do.call(tabsetPanel, myTabs) - Alpi Murányi

4
有一种方法可以动态地添加tabPanels而不使用renderUI,这可能不像使用renderUI版本那么明显。我编写了一个名为addTabToTabset的函数,它将任何(列表)tabPanel追加到选项卡集/导航栏中。
与使用renderUI相比,这种方法具有一组优势
  • 每次添加新面板时不会重新渲染现有的tabPanels。(更快)
  • 因此,不会重置现有面板内部的所有输入变量。(不需要存储变量的解决方法)
  • 可以单独选择面板内容的结构。(在lapply-renderUI版本中,所有面板都必须稍微统一。)
解决方案和代码示例可以在这里找到。如果需要,我还可以在此发布代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接