I am trying to build my own tabsets functionality in shiny using plain javascript. This is partly an exercise for me to learn javascript and the inner workings of shiny as well as to create functions which give the user greater flexibility when it comes to styling of tabsets.R
So far I have come up with the following (based on
Tab 2 - Bad (plot not rendered)
CodePudding user response:
Trigger the shown
event on your tab content.
library(shiny)
js <- shiny::HTML('
<script>
const tabs = document.querySelectorAll(".tab");
const contents = document.querySelectorAll(".tab-content");
// "activate" the first content
contents[0].classList.add("show-content");
tabs[0].classList.add("active-nav");
tabs.forEach(tab => tab.addEventListener("click", function() {
// remove active-nav and show-content classes
tabs.forEach(tab => tab.classList.remove("active-nav"));
contents.forEach(c => c.classList.remove("show-content"));
// highlight the contents
document.getElementById(tab.id).classList.add("active-nav");
let showEl = document.getElementById(tab.id "-content")
showEl.classList.add("show-content");
$(showEl).trigger("shown");
}));
</script>
')
css <- shiny::HTML(
'
<style>
ul {
margin: 0;
padding: 0;
}
.tab {
display: inline-block;
border: 1px solid lightgrey;
padding: 10px;
cursor: pointer;
}
.active-nav {
background: lightgrey;
}
.tab-content {
display: none;
padding: 10px;
}
.show-content {
display: block;
background: lightgray;
}
</style>
'
)
ui <- div(
tags$ul(
tags$li(class = "tab", id = "tab1", "data-value" = "Tab 1 CAP", "Tab 1 CAP"),
tags$li(class = "tab", id = "tab2", "data-value" = "Tab 2 CAP", "Tab 2 CAP")
),
div(, id="tab1-content", "data-value" = "Tab 1 CAP",
p("1 first tab"),
plotOutput("plot1")
),
div(, id="tab2-content", "data-value" = "Tab 2 CAP",
p("2 second tab"),
plotOutput("plot2")),
css,
js
)
server <- function(input, output, session) {
output$plot1 <- renderPlot({
plot(1:10, rnorm(10))
})
output$plot2 <- renderPlot({
plot(1:100, rnorm(100))
})
}
shinyApp(ui, server)
Shiny plotting is bound to the shown
event.