Reputation: 2022
The app below contains two vertical tabsets. I would like to keep track of the active tab for each. I am using the following JQuery function to do this:
function getActiveTab(ns, id) {
$('#' + ns + id).click(function() {
var active = $(this).next('a.active').data('value');
Shiny.setInputValue(ns + 'active_tab', active);
});
}
However, it doesn't seem to return anything when I check the inspector in Chrome. I'm not sure if it's because I'm using the wrong selector (wasn't sure if it would be better to use children
or find
instead of next
- I've tried all three to no avail.) or if the source is being loaded properly when the app starts up and was wondering if someone could shed some light?
Here is the full app:
library(shiny)
library(shinyWidgets)
library(shinyjs)
# MODULE 1 ----------------------------------------------------------------
modUI <- function(id) {
ns <- NS(id)
tagList(
verticalTabsetPanel(
id = ns('tabs'), contentWidth = 8,
verticalTabPanel(
id = ns('tab1'),
title = ns('tab1'), ''
),
verticalTabPanel(
id = ns('tab2'),
title = ns('tab2'), ''
)
)
)
}
modServer <- function(input, output, session) {
ns = session$ns
shinyjs::runjs(sprintf("getActiveTab(ns = '%s', id = '%s');", ns(''), 'tabs'))
observe(print(input$active_tab))
}
# MAIN APP ----------------------------------------------------------------
shinyApp(
ui = fluidPage(
useShinyjs(),
tags$head(tags$script("function getActiveTab(ns, id) {
$('#' + ns + id).on('click', function(el) {
var active_tab = el.find('a.active').data('value');
Shiny.setInputValue(ns + 'active_tab', active_tab);
});
}")),
modUI('mod1'), modUI('mod2')
),
server = function(input, output) {
callModule(modServer, 'mod1')
callModule(modServer, 'mod2')
}
)
EDIT: The followed worked:
function getActiveTab(ns, id) {
$('#' + ns + id).click(function() {
var active = $(this).children('.active').data('value');
Shiny.setInputValue(ns + 'active_tab', active);
});
}
But why doesn't next('a.active')
or children('a.active')
work?
Upvotes: 0
Views: 536
Reputation: 17689
You could do it in plain shiny:
Just use input$IDOFVERTTABSETPANEL
. There should be similar questions, but probably not wrapped in a module.
Reproducible code:
library(shiny)
tabs<- function(id, label = "Counter") {
ns <- NS(id)
tagList(
verticalTabsetPanel(id = ns("button"),
verticalTabPanel(
title = "Title 1", icon = icon("home", "fa-2x"),
"Content panel 1"
),
verticalTabPanel(
title = "Title 2", icon = icon("map", "fa-2x"),
"Content panel 2"
)
)
)
}
tabTrack <- function(input, output, session) {
observeEvent(input$button, {
print(input$button)
})
}
ui <- fluidPage(
tabs("counter1", "Counter #1")
)
server <- function(input, output, session) {
callModule(tabTrack, "counter1")
}
shinyApp(ui, server)
Upvotes: 1