I'm working on a self-contained flexdashboard project and I'm wondering if it's possible when a user clicks to a new tab in one tabset, it changes to a new tab on a second tabset as well.
So for example, when you click on "Chart B1" below, I would also like to change view to "Chart B2" in the second column. And clicking on "Chart A2" would change back to "Chart A1", etc. etc.
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
---
```{r setup, include=FALSE}
library(flexdashboard)
```
Column {.tabset}
-----------------------------------------------------------------------
### Chart A1
### Chart B1
Column {.tabset}
-----------------------------------------------------------------------
### Chart A2
### Chart B2
Note, this was first posted on RStudio Community, but did not receive any responses.
Just found out that it is not currently possible as tabs have to cover full row github.com/rstudio/flexdashboard/issues/37. # Your tabset title ================================ (tabset content) I'm running version 1.0.143 of R-Studio, version 1.8 of rmarkdown, and 0.5.1 version of flexdashboard. Tabs work nicely with flexdashboard.
With flexdashboard, title levels have different meaning, and the first 3 each serves a purpose. Level 2 are for definining the layout, Row or Column. See about orientation Level 3 are for defining the component, and define the title of each boxes. See about title. They are also uses to defines tabset name (See about tab row
The width of charts in flexdashboard is ultimately determined by the width of the browser. If your layout has a single column then charts will occupy the full width of the browser. If your layout has multiple columns then the columns will split the available width evenly (unless overridden via the data-width attribute as described below).
To set up a flexdashboard, install the package from CRAN using the standard command. To get started, enter the following into the console: This function creates a .Rmd file with the name associated file name, and uses the package’s flexdashboard template.
This can be implemented with JavaScript. Luckily, Knitr supports embedded Javascript. I am an R programmer foremost, so this may not necessarily be the most concise implementation, but it does achieve the correct effect.
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
---
```{r setup, include=FALSE}
library(flexdashboard)
```
Column {.tabset}
-----------------------------------------------------------------------
### Chart A1
Chart A1 is Great
### Chart B1
Chart B1 is Great
Column {.tabset}
-----------------------------------------------------------------------
### Chart A2
Chart A2 is Great
### Chart B2
Chart B2 is Great
```{js}
// Once the Document Has Fully Loaded
document.addEventListener("DOMContentLoaded", function(){
// Select The Tabs
window.a1Tab = document.querySelector("#column > ul > li:nth-child(1)");
window.b1Tab = document.querySelector("#column > ul > li:nth-child(2)");
window.a2Tab = document.querySelector("#column-1 > ul > li:nth-child(1)");
window.b2Tab = document.querySelector("#column-1 > ul > li:nth-child(2)");
// Select the Panel Content
window.a1Panel = document.getElementById('chart-a1');
window.b1Panel = document.getElementById('chart-b1');
window.a2Panel = document.getElementById('chart-a2');
window.b2Panel = document.getElementById('chart-b2');
// If We Click on B1, Open B2, Close A2
b1Tab.addEventListener('click', function(){
a2Tab.classList.remove('active');
a2Tab.children[0].setAttribute('aria-expanded', true);
a2Panel.classList.remove('active');
b2Tab.classList.add('active');
b2Tab.children[0].setAttribute('aria-expanded', true);
b2Panel.classList.add('active');
}, false);
// If We Click on B2, Open B1, Close A1
b2Tab.addEventListener('click', function(){
a1Tab.classList.remove('active');
a1Tab.children[0].setAttribute('aria-expanded', true);
a1Panel.classList.remove('active');
b1Tab.classList.add('active');
b1Tab.children[0].setAttribute('aria-expanded', true);
b1Panel.classList.add('active');
}, false);
// If We Click on A1, Open A2, Close B2
a1Tab.addEventListener('click', function(){
b2Tab.classList.remove('active');
b2Tab.children[0].setAttribute('aria-expanded', true);
b2Panel.classList.remove('active');
a2Tab.classList.add('active');
a2Tab.children[0].setAttribute('aria-expanded', true);
a2Panel.classList.add('active');
}, false);
// If We Click on A2, Open A1, Close B1
a2Tab.addEventListener('click', function(){
b1Tab.classList.remove('active');
b1Tab.children[0].setAttribute('aria-expanded', true);
b1Panel.classList.remove('active');
a1Tab.classList.add('active');
a1Tab.children[0].setAttribute('aria-expanded', true);
a1Panel.classList.add('active');
}, false);
});
```
Edit: For an unlimited number of tabs, assuming that you will always have the same number of tabs in the first and second column. Same disclaimer, this is not necessarily the most concise implementation, but achieves the desired effect.
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
---
```{r setup, include=FALSE}
library(flexdashboard)
```
Column {.tabset}
-----------------------------------------------------------------------
### Chart A1
Chart A1 is Great
### Chart B1
Chart B1 is Great
### Chart C1
Chart C1 is Great
### Chart D1
Chart D1 is Great
Column {.tabset}
-----------------------------------------------------------------------
### Chart A2
Chart A2 is Great
### Chart B2
Chart B2 is Great
### Chart C2
Chart C2 is Great
### Chart D2
Chart D2 is Great
```{js}
// Once the Document Has Fully Loaded
document.addEventListener("DOMContentLoaded", function(){
// Select The Tabs
window.col1Tabs = document.querySelector("#column > ul");
window.col2Tabs = document.querySelector("#column-1 > ul");
// Select the Panel Content
window.col1Panels = document.querySelector("#column > div");
window.col2Panels = document.querySelector("#column-1 > div");
// Function to Make Tabs Active
window.handleTab = function(tabIndex){
for(i=0;i<col1Tabs.childElementCount;i++){
col1Tabs.children[i].classList.remove('active');
col2Tabs.children[i].classList.remove('active');
col1Panels.children[i].classList.remove('active');
col2Panels.children[i].classList.remove('active');
}
col1Tabs.children[tabIndex].classList.add('active');
col2Tabs.children[tabIndex].classList.add('active');
col1Panels.children[tabIndex].classList.add('active');
col2Panels.children[tabIndex].classList.add('active');
}
// For All Tabs, Add Event Listener
for(i=0;i<col1Tabs.childElementCount;i++){
col1Tabs.children[i].setAttribute('onclick', 'handleTab(' + i + ');');
col2Tabs.children[i].setAttribute('onclick', 'handleTab(' + i + ');');
}
});
```
Edit: For anyone who may find this question later, a JQuery implementation with more flexibility was added to the Github Issue.
Just to add another answer using JQuery and boostrap tabset JS function. It is more concise than other answer but works the same with any number of tabs (but the same number) in your two column format.
---
title: "Untitled"
output:
flexdashboard::flex_dashboard:
orientation: columns
vertical_layout: fill
---
```{r setup, include=FALSE}
library(flexdashboard)
```
```{js}
document.addEventListener("DOMContentLoaded", function(){
$('a[data-toggle="tab"]').on('click', function(e){
// find the tab index that is click
child = e.target.parentNode;
tabnum = Array.from(child.parentNode.children).indexOf(child);
// find in which column we are
column = $(e.target).closest("div[id]");
// show the same tab in the other column
columnid = column.attr("id");
if (columnid == "column") {
columnto = "column-1";
} else {
columnto = "column";
}
$("div[id="+columnto+"] li:eq("+tabnum+") a").tab('show');
})
});
```
Column {.tabset}
-----------------------------------------------------------------------
### Chart A1
This is a text
### Chart B1
```{r}
plot(iris)
```
Column {.tabset}
-----------------------------------------------------------------------
### Chart A2
```{r}
plot(mtcars)
```
### Chart B2
This is another text
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With