R Shiny - динамически добавлять tabPanel в tabsetPanel (с использованием renderUI)

Я разрабатываю блестящее приложение, в котором я использую tabsetPanel, который создается, когда пользователь вводит определенный ввод. Таким образом, я хочу использовать функцию renderUI для отображения / исчезновения tabsetPanel.

Моя борьба сейчас заключается в том, что количество tabPanel элементов (аргументы tabsetPanel) также зависит от ввода пользователя, в том числе: иногда мне нужен 1 элемент, иногда мне нужно больше tabPanels .

Как это сделать? Я попытался включить conditionPanel или включить простое условие if()... в аргумент tabsetPanel, но это (что неудивительно ...) не сработало.


person Marta Karas    schedule 19.10.2013    source источник


Ответы (2)


Ну вот. Код довольно понятен.

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)
    })
  }
))
person Ramnath    schedule 19.10.2013
comment
Рамнатх, это сделало мой день лучше, отлично работает! Большое спасибо!! - person Marta Karas; 20.10.2013
comment
Рад помочь. Если у вас есть вопросы по самому коду, напишите здесь. - person Ramnath; 20.10.2013
comment
Дополнение: как только у вас есть добавленные вкладки, как правильно добавить одинаковый uiOutput на все вкладки, но сделать значения уникальными для каждой вкладки? Или это другое? Если вы добавите output$base_tab_ui и отобразите их в каждом, все они будут иметь одинаковый input$value для каждой вкладки. Есть ли способ сделать их уникальными с разными именами входных переменных? - person Jenks; 20.10.2016
comment
@Ramnath, как бы вы занялись заполнением каждой из этих динамических вкладок собственным содержимым? возможно, скажем, renderTable / tableOutput для data.frame, который можно отфильтровать с использованием того же объекта, который я использовал для заполнения имен вкладок (т.е. nTabs = length(lags_7) и myTabs = lapply(sprintf('%s', lags_7), tabPanel)) (возможный ответ здесь: stackoverflow.com/questions/ 39276104 /) - person d8aninja; 25.01.2018
comment
@ d8aninja, предполагая, что у вас есть несколько графиков, добавленных в список под названием myPlots, вы можете сделать: nTabs = length(myPlots); myTabs = lapply(1:nTabs, function(x){tabPanel(paste0("Tab ",x), renderPlot(myPlots[[x]]))}); do.call(tabsetPanel, myTabs) - person Alpi Murányi; 03.12.2019

Есть способ динамически добавлять tabPanels без renderUI, что может быть не так очевидно, как версия с renderUI. Я написал функцию addTabToTabset, которая добавит любой (список) tabPanel (s) к tabset / navbar.

У этого подхода есть ряд преимуществ перед использованием renderUI:

  • Существующие tabPanel не обновляются каждый раз при добавлении новой панели. (Быстрее)
  • Таким образом, не сбрасываются все входные переменные внутри существующих панелей. (обходные пути для хранения переменных не требуются)
  • Структура содержимого панели может быть выбрана индивидуально. (В версии lapply - renderUI все панели должны быть в некоторой степени однородными.)

Решение и образец кода можно найти в ответе здесь. Если потребуется, я также могу разместить здесь код.

person K. Rohde    schedule 17.04.2016