Programatically change selected side-nav-tab
Opened this issue ยท 8 comments
We need to programatically select a side nav tab. We tried to adapt the example from @bilbaoba 's example from this question regarding tabs: #79 but cannot get it to work.
Here is what we have tried:
library(shiny)
library(shinymaterial)
ui <- material_page(
title = "Basic Page + Side-Nav with Tabs",
nav_bar_fixed = TRUE,
material_side_nav(fixed = TRUE,
material_side_nav_tabs(
side_nav_tabs = c(
"Example Side-Nav Tab 1" = "example_side_nav_tab_1",
"Example Side-Nav Tab 2" = "example_side_nav_tab_2"
),
icons = c("cast", "insert_chart")
)),
material_side_nav_tab_content(
side_nav_tab_id = "example_side_nav_tab_1",
material_button(input_id = "button", label = "GO TO SECOND SIDE NAV TAB")
),
material_side_nav_tab_content(
side_nav_tab_id = "example_side_nav_tab_2",
tags$h1("Second Side-Nav Tab Content"))
)
server <- function(input, output, session) {
observe({
if (input$button == 0)
return()
js_code <-
"$('li.shiny-material-side-nav-tab a[href$=\"#example_side_nav_tab_2_tab_id\"]:first').trigger(\"click\");"
session$sendCustomMessage(type = "shinymaterialJS", js_code)
})
}
shinyApp(ui = ui, server = server)
Any help on this would be much appreciated. Thank you
(I did ask this on SO too https://stackoverflow.com/questions/56789753/programatically-change-selected-nav-tab-in-r-shinymaterial-app but had no response)
I once wrote a JS function to select a normal (not side nav) tab:
shinyjs.select_material_TopTab = function(tab_id){
var tab = $("ul.tabs li.tab a[href$=" + tab_id + "]");
tab.trigger("click");
}
in the UI:
shinyjs::useShinyjs(),
shinyjs::extendShinyjs(text = jsCode, functions = c("select_material_TopTab")),
and in the server.R
js$select_material_tab("tab1") # change the id (without '_tab_id' at the end)
Maybe this can be adapted to the side nav bar?
Hi @Seyphaton thanks so much for this. I have tried to build into my example but with no luck so far. Any thoughts on what I could try?
library(shiny)
library(shinyjs)
library(shinymaterial)
jsCode <-
'select_material_Tab = function(tab_id){
var tab = $("ul.tabs li.tab a[href$=" + tab_id + "]");
tab.trigger("click");
}'
ui <- material_page(
title = "Basic Page + Side-Nav with Tabs",
nav_bar_fixed = TRUE,
shinyjs::useShinyjs(),
shinyjs::extendShinyjs(
text = jsCode,
functions = c("select_material_Tab")
),
material_side_nav(fixed = TRUE,
material_side_nav_tabs(
side_nav_tabs = c(
"Example Side-Nav Tab 1" = "example_side_nav_tab_1",
"Example Side-Nav Tab 2" = "example_side_nav_tab_2"
),
icons = c("cast", "insert_chart")
)),
material_side_nav_tab_content(
side_nav_tab_id = "example_side_nav_tab_1",
material_button(input_id = "button", label = "GO TO SECOND SIDE NAV TAB")
),
material_side_nav_tab_content(side_nav_tab_id = "example_side_nav_tab_2",
tags$h1("Second Side-Nav Tab Content"))
)
server <- function(input, output, session) {
observeEvent(input$button, ignoreInit = T, {
session$sendCustomMessage(type = "shinymaterialJS", js$select_material_Tab("example_side_nav_tab_2"))
})
}
shinyApp(ui = ui, server = server)
Hi everybody,
@ericrayanderson thanks for providing this package, despite some glitches and it's minimalistic footprint, it has really served me well.
I see the tab activation (including navbar) is an open issue which hasn't received a general implementation, yet. #79 apparently is tailored towards regular tabs and there currently isn't a way to generally active/switch tabs within the shinymaterial framework, without reverse-engineering and writing JavaScript code. I know some R but I'm definitely not a JavaScript developer.
Also, the function in commit f8c920d is not available in the latest release 0.5.0.
I can imagine two ways to integrate this:
- Using custom function as in regular Shiny, see updateTabsetPanel(). However, shinymaterial widgets lack an id field to control this.
- By registering callback functions for each tabset-like UI element to activate a tab, e.g. in the output object
Is there a chance to include a general solution? All I understand it would take adding a little JavaScript magic to the existing code.
Thanks!
Exactly @fungs, it was solved in the PR #81. I don't know why @ericrayanderson suppress the function.
I can rewrite it and make another PR. Maybe also implement other features of material tabs like disable
.
Any work would be appreciated, I volunteer for testing :)
Hi @Seyphaton thanks so much for this. I have tried to build into my example but with no luck so far. Any thoughts on what I could try?
library(shiny) library(shinyjs) library(shinymaterial) jsCode <- 'select_material_Tab = function(tab_id){ var tab = $("ul.tabs li.tab a[href$=" + tab_id + "]"); tab.trigger("click"); }' ui <- material_page( title = "Basic Page + Side-Nav with Tabs", nav_bar_fixed = TRUE, shinyjs::useShinyjs(), shinyjs::extendShinyjs( text = jsCode, functions = c("select_material_Tab") ), material_side_nav(fixed = TRUE, material_side_nav_tabs( side_nav_tabs = c( "Example Side-Nav Tab 1" = "example_side_nav_tab_1", "Example Side-Nav Tab 2" = "example_side_nav_tab_2" ), icons = c("cast", "insert_chart") )), material_side_nav_tab_content( side_nav_tab_id = "example_side_nav_tab_1", material_button(input_id = "button", label = "GO TO SECOND SIDE NAV TAB") ), material_side_nav_tab_content(side_nav_tab_id = "example_side_nav_tab_2", tags$h1("Second Side-Nav Tab Content")) ) server <- function(input, output, session) { observeEvent(input$button, ignoreInit = T, { session$sendCustomMessage(type = "shinymaterialJS", js$select_material_Tab("example_side_nav_tab_2")) }) } shinyApp(ui = ui, server = server)
JQUery/JS solution (basically just repeating the on click behaviour)
shinyjs.select_material_sidenav_tab = function(tab_id){
$('.shiny-material-side-nav-tab-content').hide();
$('.shiny-material-side-nav-tab-content').trigger('hide');
$('.shiny-material-side-nav-tab-content').trigger('hidden');
$('.shiny-material-side-nav-tab').removeClass('active');
$('#' + tab_id).show();
$('#' + tab_id).trigger('show');
$('#' + tab_id).trigger('shown');
$('#' + tab_id + '_tab_id').addClass('active');
$('#side_nav_tabs_click_info').trigger('click');
}
Hi @analytichealth @Seyphaton , thank you for your previous responses to this issue. @Seyphaton any suggestion on how to programatically hide (and/or disable) a tab in material_tabs()
given your JQUery/JS solution? I've been attempting to adapt your solution and only seem to be able to hide the content within the tab, not the tab itself.
Try this:
shinyjs.disableTab = function(name) {
var tab = $('.nav li a[data-value=' + name + ']');
tab.bind('click.tab', function(e) {
e.preventDefault();
return false;
});
tab.addClass('disabled');
};
shinyjs.hideTab = function(name) {
var tab = $('.nav li a[data-value=' + name + ']');
tab.bind('click.tab', function(e) {
e.preventDefault();
return false;
});
tab.addClass('invisible');
};