I have shiny application with several tabs.
The problem is that I want to walk between tabs with button, not by clicking on the tab. How I can disable clicking on tabs?
Small example of code:
ui <- navbarPage('Test App', id = "inTabset",
tabPanel(title = "Panel 1", value = "panel1",
actionButton('jumpToP2', 'Jump to Secon Tab')),
tabPanel(title = "Panel 2", value = "panel2",
actionButton('jumpToP1', 'Jump to First Tab'))
)
server <- function(input, output, session) {
observeEvent(input$jumpToP2, {
updateTabsetPanel(session, "inTabset",
selected = "panel2")
})
observeEvent(input$jumpToP1, {
updateTabsetPanel(session, "inTabset",
selected = "panel1")
})
}
shinyApp(ui, server)
Here is a possible workaround. We can use shinyjs to disable the navbar buttons, and add some CSS to change the cursor to default when hovering the navigation bar.
There may be simpler ways that I am not aware of, so I am curious to see other possible solution approaches :) Hope this helps!
library(shiny)
library(shinyjs)
ui <- navbarPage('Test App', id = "inTabset",
tabPanel(title = "Panel 1", value = "panel1",
actionButton('jumpToP2', 'Jump to Secon Tab')),
tabPanel(title = "Panel 2", value = "panel2",
actionButton('jumpToP1', 'Jump to First Tab')),
useShinyjs(),
tags$head(tags$style(HTML('.navbar-nav a {cursor: default}')))
)
server <- function(input, output, session) {
shinyjs::disable(selector = '.navbar-nav a')
observeEvent(input$jumpToP2, {
updateTabsetPanel(session, "inTabset",
selected = "panel2")
})
observeEvent(input$jumpToP1, {
updateTabsetPanel(session, "inTabset",
selected = "panel1")
})
}
shinyApp(ui, server)
Related
I want to hide a tabsetPanel in a ShinyApp. Following this answer in a Shiny issue I can do that just fine like this:
library(shiny)
ui <- fluidPage(
tags$style("#inTabset { display:none; }"), #This works
sidebarLayout(
sidebarPanel(
sliderInput("controller", "Controller", 1, 3, 1)
),
mainPanel(
tabsetPanel(id = "inTabset",
tabPanel(title = "Panel 1", value = "panel1", "Panel 1 content"),
tabPanel(title = "Panel 2", value = "panel2", "Panel 2 content"),
tabPanel(title = "Panel 3", value = "panel3", "Panel 3 content")
)
)
)
)
server <- function(input, output, session) {
observeEvent(input$controller, {
updateTabsetPanel(session, "inTabset", selected = paste0("panel", input$controller))
})
}
shinyApp(ui, server)
However, I'm using bslib for theming. This library seems to modify the css selectors involved and I can't seem to figure out how to modify the tabsetPanel selector to hide it:
library(shiny)
library(bslib)
ui <- fluidPage(
theme = bs_theme(primary = "#EA80FC"),
tags$style("#inTabset { display:none; }"), #This no longer works,
sidebarLayout(
sidebarPanel(
sliderInput("controller", "Controller", 1, 3, 1)
),
mainPanel(
tabsetPanel(id = "inTabset",
tabPanel(title = "Panel 1", value = "panel1", "Panel 1 content"),
tabPanel(title = "Panel 2", value = "panel2", "Panel 2 content"),
tabPanel(title = "Panel 3", value = "panel3", "Panel 3 content")
)
)
)
)
server <- function(input, output, session) {
observeEvent(input$controller, {
updateTabsetPanel(session, "inTabset", selected = paste0("panel", input$controller))
})
}
shinyApp(ui, server)
I tried inspecting and playing with the elements shown in chrome's dev console to no avail. So, how do I reference this element when using bslib?
Not sure what's the reason you want to hide the tabs via CSS when you could achieve the same result via type="hidden" which also seems to work fine with bslib:
library(shiny)
library(bslib)
ui <- fluidPage(
theme = bs_theme(primary = "#EA80FC"),
sidebarLayout(
sidebarPanel(
sliderInput("controller", "Controller", 1, 3, 1)
),
mainPanel(
tabsetPanel(id = "inTabset",
type = "hidden",
tabPanel(title = "Panel 1", value = "panel1", "Panel 1 content"),
tabPanel(title = "Panel 2", value = "panel2", "Panel 2 content"),
tabPanel(title = "Panel 3", value = "panel3", "Panel 3 content")
)
)
)
)
server <- function(input, output, session) {
observeEvent(input$controller, {
updateTabsetPanel(session, "inTabset", selected = paste0("panel", input$controller))
})
}
shinyApp(ui, server)
#>
#> Listening on http://127.0.0.1:3626
How can I move from one tab to another using actionButton() when then name of the tab is dynamic in a shiny app?
library(shiny)
ui <- fluidPage(
tabsetPanel(
id="inTabset",
tabPanel("Tab 1",textInput("name","Name"),actionButton("switch_tab", "Go to the third tab")
),
tabPanel("Tab 2", "there!"),
tabPanel(textOutput("TAB3")))
)
server <- function(input, output, session) {
observeEvent(input$switch_tab, {
updateTabsetPanel(session, "inTabset",selected = "Tab 3")
})
output$TAB3<-renderText({
if(input$name==""){
"Tab 3"
}
else{
paste(input$name)
}
})
}
shinyApp(ui = ui, server = server)
Just use tabPanel's value parameter:
From ?tabPanel:
value - The value that should be sent when tabsetPanel reports that this tab is selected. If omitted and tabsetPanel has an id, then
the title will be used.
library(shiny)
ui <- fluidPage(tabsetPanel(
id = "inTabset",
tabPanel(
"Tab 1",
textInput("name", "Name"),
actionButton("switch_tab", "Go to the third tab")
),
tabPanel("Tab 2", "there!"),
tabPanel(textOutput("TAB3"), value = "TAB3")
))
server <- function(input, output, session) {
observeEvent(input$switch_tab, {
updateTabsetPanel(session, "inTabset", selected = "TAB3")
})
output$TAB3 <- renderText({
if (input$name == "") {
"Tab 3"
} else{
paste(input$name)
}
})
}
shinyApp(ui = ui, server = server)
I would like to have one of the tabPanels in my Shiny app launch a shinyFiles style input. In this case I would like to launch a shinySaveButton, without the shinySaveButton being in my dataset (By clicking the save icon [which is actually a tabPanel])
Reproducible example below
library(shiny)
library(shinyFiles)
ui <- navbarPage('Test App',id = "inTabset", selected="panel1",
tabPanel(title = "", value = "Save", icon = icon("save")),
tabPanel(title = "Panel 1", value = "panel1",
h1("Panel1")),
tabPanel(title = "Panel 2",value = "panel2",
h1("Panel2"))
)
server <- function(input, output, session) {
values = reactiveValues(tabSelected="panel1")
observe({
if (input$inTabset=="Save") {
updateNavbarPage(session,"inTabset",selected=values$tabSelected)
#CODE FOR LOADING SHINYFILES DIALOG IN HERE
} else {
values$tabSelected<-input$inTabset
}
})
}
shinyApp(ui, server)
Any help would be greatly appreciated.
Work around using hidden element trick
library(shiny)
library(shinyFiles)
library(shinyjs)
jsCode<-"shinyjs.saveButton=function(){ $('#buttonFileSaveHidden').click(); }"
ui <- fluidPage(
useShinyjs(),
extendShinyjs(text = jsCode),
navbarPage('Test App',id = "inTabset", selected="panel1",
tabPanel(title = "", value = "Save", icon = icon("save")),
tabPanel(title = "Panel 1", value = "panel1",
h1("Panel1")
),
tabPanel(title = "Panel 2",value = "panel2",
h1("Panel2"))
),
# HIDDEN BUTTON TO INITIATE THE SAVE
hidden(shinySaveButton( "buttonFileSaveHidden",
label="",
title="Save as ...",
list('hidden_mime_type'=c("R")),
class='hiddenButton')),
wellPanel( #ONLY INCLUDED TO DISPLAY OF PATH INFO OF THE CHOICE
h3('Current save path info'),
tableOutput('table')
)
)
server <- function(input, output, session) {
values = reactiveValues(tabSelected="panel1")
observe({
if (input$inTabset=="Save") {
updateNavbarPage(session,"inTabset",selected=values$tabSelected)
#CODE FOR LOADING SHINYFILES DIALOG IN HERE
js$saveButton()
} else {
values$tabSelected<-input$inTabset
}
})
shinyFileSave(input, "buttonFileSaveHidden", session=session, roots=c(wd="~"), filetypes=c('R') ) #hidden
# GET THE SAVE PATH CHOICE AND RECORD IT IN fp.dt.rv
fp.dt.rv<-reactiveVal("")
observeEvent(input$buttonFileSaveHidden,{
fp.dt<-parseSavePath(c(wd='~'), input$buttonFileSaveHidden)
fp.dt.rv(fp.dt) #or just use to immediately write.
})
# ONLY TO DISPLAY THE SAVE CHOICE
output$table <- renderTable(fp.dt.rv())
}
shinyApp(ui, server)
every one, I want to make a shiny app, which can disable tables in a specific navlistPanel, follow is my code which can disabe all the tabs in navlistPanel:
ui <- fluidPage(
useShinyjs(),
navlistPanel(id = "inTabset1",
tabPanel(title = "Panel 1", value = "panel1",
actionButton('jumpToP2', 'Jump to Second Tab')),
tabPanel(title = "Panel 2", value = "panel2",
actionButton('jumpToP1', 'Jump to First Tab'))
# tags$head(tags$style(HTML('.navbar-nav a {cursor: default}')))),
navlistPanel(id = "inTabset2",
tabPanel(title = "Panel 3", value = "panel3",
actionButton('jumpToP3', 'Jump to fouth Tab')),
tabPanel(title = "Panel 4", value = "panel4",
actionButton('jumpToP4', 'Jump to third Tab'))
# tags$head(tags$style(HTML('.navbar-nav a {cursor: default}')))))
server <- function(input, output, session) {
# shinyjs::disable(selector = '.navbar-nav a'
shinyjs::disable(
# id = "inTabset1",
selector = '.nav li a'
)
observeEvent(input$jumpToP2, {
updateTabsetPanel(session, "inTabset1",
selected = "panel2")
})
observeEvent(input$jumpToP1, {
updateTabsetPanel(session, "inTabset1",
selected = "panel1")
})
observeEvent(input$jumpToP3, {
updateTabsetPanel(session, "inTabset2",
selected = "panel4")
})
observeEvent(input$jumpToP4, {
updateTabsetPanel(session, "inTabset2",
selected = "panel3")
})}
shinyApp(ui, server)
Those code can disable all the tabs in two navlistPanle. However, when I want to only disable the tabs in the first navlistPanel, inTabset1, so I add the id to the function of disable like this:
shinyjs::disable(
id = "inTabset1",
selector = '.nav li a'
)
It did not work any more! All the tabs are not disabled! So any guys can help me for this question? Thanks very much!
You can not use both the arguments id and selector in disable, see the documentation for the function here:
id The id of the input element/Shiny tag
selector Query selector of
the elements to target. Ignored if the id argument is given. For
example, to disable all text inputs, use selector =
"input[type='text']"
What you could do however, is change your selector to '#inTabset1 li a', so it will disable all elements of class a that are in an element class li that are in the element with id inTabset1.
Here is a working example, I hope this helps!
library(shiny)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
navlistPanel(id = "inTabset1",
tabPanel(title = "Panel 1", value = "panel1",
actionButton('jumpToP2', 'Jump to Second Tab')),
tabPanel(title = "Panel 2", value = "panel2",
actionButton('jumpToP1', 'Jump to First Tab'))),
# tags$head(tags$style(HTML('.navbar-nav a {cursor: default}')))),
navlistPanel(id = "inTabset2",
tabPanel(title = "Panel 3", value = "panel3",
actionButton('jumpToP3', 'Jump to fouth Tab')),
tabPanel(title = "Panel 4", value = "panel4",
actionButton('jumpToP4', 'Jump to third Tab'))
# tags$head(tags$style(HTML('.navbar-nav a {cursor: default}')))))
)
)
server <- function(input, output, session) {
# shinyjs::disable(selector = '.navbar-nav a'
shinyjs::disable(
selector = '#inTabset1 li a'
)
observeEvent(input$jumpToP2, {
updateTabsetPanel(session, "inTabset1",
selected = "panel2")
})
observeEvent(input$jumpToP1, {
updateTabsetPanel(session, "inTabset1",
selected = "panel1")
})
observeEvent(input$jumpToP3, {
updateTabsetPanel(session, "inTabset2",
selected = "panel4")
})
observeEvent(input$jumpToP4, {
updateTabsetPanel(session, "inTabset2",
selected = "panel3")
})}
shinyApp(ui, server)
I need the user to click a button and be taken to a different tabPanel of a navbarPage. Here is a simple app where this could be implemented. How can I achieve this?
ui <- shinyUI(
navbarPage('Test App',
tabPanel('Page 1',
p('This is the first tab'), br(),
actionButton('jumpToP2', 'Jump to Second Tab')
),
tabPanel('Page 2',
p('This is the second tab'),
actionButton('jumpToP1', 'Jump to First Tab')
)
)
)
server <- shinyServer(function(input, output){
observeEvent(input$jumpToP2,{
## Switch active tab to 'Page 2'
})
observeEvent(input$jumpToP1,{
## Switch active tab to 'Page 1'
})
})
shinyApp(ui, server)
You can use updateTabsetPanel to switch between different tabPanels. See the documentation and example codes at https://shiny.rstudio.com/reference/shiny/latest/updateTabsetPanel.html. The code below should fulfill your requirements.
ui <- navbarPage('Test App',id = "inTabset",
tabPanel(title = "Panel 1", value = "panel1",
actionButton('jumpToP2', 'Jump to Second Tab')),
tabPanel(title = "Panel 2", value = "panel2",
actionButton('jumpToP1', 'Jump to First Tab'))
)
server <- function(input, output, session) {
observeEvent(input$jumpToP2, {
updateTabsetPanel(session, "inTabset",
selected = "panel2")
})
observeEvent(input$jumpToP1, {
updateTabsetPanel(session, "inTabset",
selected = "panel1")
})
}
shinyApp(ui, server)
I'm not so sure that this really the best way for you to design your U... Do you know that tabPanel() will act pretty much the same way as an actionButton() will in this case?
ui <- navbarPage('Test App',id = "inTabset",
tabPanel(title = "Panel 1", uiOutput("panel1")),
tabPanel(title = "Panel 2", uiOutput("panel2"))
)
server <- function(input, output, session) {
output$panel1 <- renderUI({
#your UI data
})
output$panel2 <- renderUI({
#your UI data
})
}
shinyApp(ui, server)