2017-03-06 66 views
0

在Rmarkdown动态标签,它可以创建标签,例如:创建于Rmarkdown

--- 
output: html_document 
--- 

# Tabs {.tabset} 

## Tab 1 

foo 

## Tab 2 

bar 

我不知道是否有可能创建的标签任意数量?如何以编程方式创建选项卡?

以下代码很难做到这一点,但它会产生一个标题而不是标签。

--- 
output: html_document 
--- 

# Tabs {.tabset} 

```{r echo=FALSE} 
shiny::tags$h2("Tab 1") 
``` 

foo 

## Tab 2 

bar 

解决方案

感谢@GGamba提供一个很好的解决方案。我需要更进一步,并能够将选项卡添加为循环的一部分,因此我需要进行两项更改。首先,我用这个代码,动态地添加标签(这里唯一的区别是,我强迫的hrefCode评价超时内,否则召集所有超时将使用相同的值)

(function(hrefCode){setTimeout(function(){ 
var tabContent = document.createElement('div'); 
var tabContainerTarget = document.getElementsByClassName('tab-content')[0]; 

    tabContent.setAttribute('id', 'tab-' + hrefCode); 
    tabContent.setAttribute('class', 'tab-pane') 
    tabContent.innerHTML = '", gsub('\n', '', Panel, fixed = TRUE), "'; 

    tabContainerTarget.appendChild(tabContent); 
    }, 100); 
})(hrefCode); 

其次,添加标签在一个循环中,你可以做这样的事情:

tabsToAdd <- list("tab3" = "hello", "tab4" = "world") 

shiny::tagList(lapply(names(tabsToAdd), function(x) { 
    addToTabset(title = x, tabsetId = 'tbSet1', 
       tabPanel(x, tabsToAdd[[x]])) 
})) 

回答

1

据我知道你正在尝试做的是不是在rmarkdown可能(但我很乐意指正)。但是我们当然可以实现一个功能来做到这一点。

我根据我的回答this回答@KRohde,所以所有的积分都归他。我只是调整它在一个简单的降价文件中工作。

答案大多与JS,而不是R建立,但由于降价主要是一个HTML我觉得JS是更好的工具。

下面是代码:

--- 
output: html_document 
--- 


```{r echo=FALSE, results='asis'} 
library(shiny) 
addToTabset <- function(title, tabsetId, Panel) { 

    tags$script(HTML(paste0(" 
        /* Getting the right tabsetPanel */ 
        var tabsetTarget = document.getElementById('", tabsetId, "'); 

        /* Creating 6-digit tab ID and check, whether it was already assigned. */ 
        hrefCode = Math.floor(Math.random()*100000); 

        /* Creating node in the navigation bar */ 
        var navNode = document.createElement('li'); 
        var linkNode = document.createElement('a'); 

        linkNode.appendChild(document.createTextNode('", title, "')); 
        linkNode.setAttribute('data-toggle', 'tab'); 
        linkNode.setAttribute('data-value', '", title, "'); 
        linkNode.setAttribute('href', '#tab-' + hrefCode); 

        navNode.appendChild(linkNode); 
        tabsetTarget.appendChild(navNode); 
        setTimeout(function(){ 
        var tabContent = document.createElement('div'); 
        var tabContainerTarget = document.getElementsByClassName('tab-content')[0]; 

         tabContent.setAttribute('id', 'tab-' + hrefCode); 
         tabContent.setAttribute('class', 'tab-pane') 
         tabContent.innerHTML = '", gsub('\n', '', Panel, fixed = T), "'; 

         tabContainerTarget.appendChild(tabContent); 
         }, 100); 
        ") 
)) 
} 

``` 

上面的代码应该留在“设置块”,因为它定义R函数调用JS功能大多只是加上正确的事情的DOM。

它可以在需要时使用,通过tabPanel标题,'目标'tabset和正常tabPanel函数。

```{r results='asis', echo=FALSE} 

shiny::tabsetPanel(id = 'tbSet1', 
        shiny::tabPanel('Tab 1', 'foo'), 
        shiny::tabPanel('Tab 2', 'bar') 
) 
``` 



```{r results='asis', echo=FALSE} 

addToTabset(title = 'Tab 3', 
      tabsetId = 'tbSet1', 
      tabPanel(
       h1('This is a title'), 
       actionButton('btn',label = 'Clicky button'), 
       radioButtons('asd', LETTERS[1:5], LETTERS[1:5]))) 

``` 
+0

如果光泽本身不能做,那是一个很好的解决方法。你是否也有一个解决方案来完成这个循环,例如。 'lapply(字母,函数(字母)addToTabset(字母,'tbSet1',tabPanel(字母,字母)))'?我不擅长高级Rmd以及如何让html正确呈现 –

+0

想通了。不得不将这个循环包装在'tagList()'中,并且还需要在javascript中进行一些修复(请参阅问题本身,以获取修改后的代码) –