Home > other >  R shiny custom tabsets using javascript - second tab not rendering
R shiny custom tabsets using javascript - second tab not rendering

Time:06-16

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 enter image description here

Tab 2 - Bad (plot not rendered) enter image description here

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.

  • Related