When I run the app, I want the tab 2 to be clicked, so I can see it first, not tab 1. How can I do so ?
# USER INTERFACE
ui <- fluidPage(
mainPanel(
tabsetPanel(
tabPanel("tab 1"),
tabPanel("tab 2"),
)
)
)
# SERVER
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
Try:
tabSetPanel(tabPanel("tab1"), tabPanel("tab2"), selected="tab2")
Related
I hope the title is self explanatory. I saw similar questions answered with JavaScript, but it would be great if it could be done with R. Here is a minimal example of what i tried and did not work (also tried updateNavbarPage()). I am trying to set a link in tabpanel B to go from tabpanel B to tabpanel D.
library(shiny)
# Define UI
ui <- fluidPage(
navbarPage(
"A",
tabPanel("A1",
sidebarPanel(),
mainPanel(
tabsetPanel(type = "tabs",
id = "panels",
# Tabsets in mainPanel----
tabPanel("B",
hr(),
HTML("This is panel B <br>"),
hr(),
actionLink("link_to_D", "Go to D")
), # Tabpanel
tabPanel("C",
hr(),
HTML("This is panel C"))
)# tabsetPanel
)# mainPanel
),#tabPanel
navbarMenu("About",
tabPanel("D",
hr(),
HTML("This is panel D")),
tabPanel("E" ,
hr(),
HTML("This is panel E"))
) #NavbarMenu
) # NavbarPage
) # fluidPage
# Define server
server <- function(input, output,session) {
# Link to D
observeEvent(input$link_to_D, {
updateTabsetPanel(session, "C", "D")
})
} # server
# Run the application
shinyApp(ui = ui, server = server)
You were close. The issue is only that in SHiny you do not update the tab panel directly. Instead you update the "mother" element which is either a tabSetPanel or - in your case - the navbarPage. So you need to give the navbarPage an id and call updateNavbarPage.
Example:
library(shiny)
# Define UI
ui <- fluidPage(
navbarPage(
"A-Title",
tabPanel("A1",
sidebarPanel(),
mainPanel(
tabsetPanel(type = "tabs",
id = "panels",
# Tabsets in mainPanel----
tabPanel("B",
hr(),
actionLink("link_to_D", "Go to D")
), # Tabpanel
tabPanel("C")
)# tabsetPanel
)# mainPanel
),#tabPanel
navbarMenu("About",
tabPanel("D", "I am D"),
tabPanel("E", "I am E")
), #NavbarMenu
id="MainNavBar" # Step 1: Give the navbarPage an id
) # NavbarPage
) # fluidPage
# Define server
server <- function(input, output,session) {
# Link to D
observeEvent(input$link_to_D, {
#--updateTabsetPanel(session, "C", "D")
# update selected tab to "D"
updateNavbarPage(inputId="MainNavBar", selected = "D")
})
} # server
# Run the application
shinyApp(ui = ui, server = server)
Assuming I have 2 action buttons as a starting page 'Client' & 'Employee' as shown below, and for each option, there is a different web application.
when the user clicks the 'Client' button I need the following code to be run:
library(shiny)
ui <-
navbarPage(
"The Client Web",
tabPanel("Section1 "),
tabPanel(" Section1 2")
)
server <- function(input, output,session){
}
shinyApp(ui = ui, server = server)
and when the user clicks the 'Employee' button I need the following code to be run:
library(shiny)
ui <-
navbarPage(
"The Employee Web",
tabPanel("Component 1"),
tabPanel("Component 2"),
tabPanel("Component 3")
)
server <- function(input, output,session){
}
shinyApp(ui = ui, server = server)
I need both of the web applications in one app depending on the type of the user either 'Client' or 'Employee'. Thank you in advance!
Using JavaScript
I would do it using Javascript code to hide/show either of the pages.
You have to create your app with de buttons and both navbarpages.
library(shiny)
ui <- fluidPage(
# Buttons
actionButton('clientsBtn', 'Clients'),
actionButton('employeeBtn', 'Employee'),
# Employee pag
div(
class = 'employees-page',
navbarPage(
"The Employee Web",
tabPanel("Component 1"),
tabPanel("Component 2"),
tabPanel("Component 3")
)
),
# Clients page
div(
class = 'clients-page',
navbarPage(
"The Client Web",
tabPanel("Section1 "),
tabPanel(" Section1 2")
)
),
# Javascript to control de page logic
includeScript('script.js')
)
server <- function(input, output,session){
}
shinyApp(ui = ui, server = server)
The script.js file is just a text file with that extension.
// hide by default the clients page
$('.clients-page').hide();
$('#clientsBtn').on('click', () => {
$('.employees-page').hide();
$('.clients-page').show();
})
$('#employeeBtn').on('click', ()=>{
$('.employees-page').show();
$('.clients-page').hide();
})
Individual pages using shiny.router
As I promised, here is the approach using {shiny.router} to accomplish what you want.
library(shiny)
library(shiny.router)
# The root page is separated from clients and employee pages
# and contains two buttons/links that takes you the destination
# you wish
root_page <- tagList(
tags$a(
div(class='btn btn-default', id='clientsBtn', 'Clients'),
href=route_link('clients')
),
tags$a(
div(class='btn btn-default', id='employeeBtn', 'Employee'),
href=route_link('employees')
)
)
# The employee and clients page should include a button/link
# to take you back to the root page. I place the button in the
# first tabpanel of each page, but for better ux is good idea
# if you place it in all of them. Consider change its style and
# position using css configuration.
employee_page <- tagList(
navbarPage(
"The Employee Web",
tabPanel(
"Component 1",
tags$a(
div(class='btn btn-default', id='home1', 'Home'),
href=route_link('/')
)
),
tabPanel("Component 2"),
tabPanel("Component 3")
)
)
clients_page <- tagList(
navbarPage(
"The Client Web",
tabPanel(
"Section1 ",
tags$a(
div(class='btn btn-default', id='home1', 'Home'),
href=route_link('/')
)
),
tabPanel(" Section1 2")
)
)
router <- make_router(
route("/", root_page),
route("employees", employee_page),
route("clients", clients_page)
)
ui <- fluidPage(
router$ui
)
server <- function(input, output, session) {
router$server(input, output, session)
}
shinyApp(ui, server)
I got theses result:
when I have tried the following code:
library(shiny)
library(shiny.router)
Cleints_page <- div(
titlePanel("Cleints"),
p("This is the Cleints web app")
)
Employees_page <- div(
titlePanel("Employees"),
p("This is the Employees web app")
)
router <- make_router(
route("/", Cleints_page),
route("employees", Employees_page)
)
ui <- fluidPage(
tags$ul(
tags$li(a(href = route_link("/"), "Cleints
Web")),
tags$li(a(href = route_link("employees"),
"Employees Web"))
),
router$ui
)
server <- function(input, output, session) {
router$server(input, output, session)
}
shinyApp(ui, server)
but still, I need each one of them to be a separate page. How I can achieve that?
I'm creating an R Shiny app that runs a function based off of many reactive widgets on multiple tabs. A problem I'm running into is that when the app is initially launched, I need to select the tabs that contain the respective reactive widgets before the widget's id is recognized in the "input". Is there a way to either 1.) have the app recognize all the reactive widgets when the app is deployed or 2.) alter the "input" initially to contain initial values for the reactive widget ids. Here is a simple example of the problem:
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel("tab 1", numericInput("a", "A", 2)),
tabPanel("tab 2", uiOutput("bUI"))
)
),
mainPanel(
verbatimTextOutput("a_b")
)
)
))
server <- function(input, output, session){
output$bUI <- renderUI({
numericInput("b", "B", 3)
})
output$a_b <- renderPrint(input$a * input$b)
}
shinyApp(ui = ui, server = server)
I initially get an output of interger(0) instead of the desired 6.
Note, I do not want to require the user to have to select all the tabs. i.e. I don't want to use req or validate to push the user to click through the tabs.
I added an intermediate check if input$b is truthy. If not, a default 3 is used:
library('shiny')
ui <- shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
tabsetPanel(
tabPanel("tab 1", numericInput("a", "A", 2)),
tabPanel("tab 2", uiOutput("bUI"))
)
),
mainPanel(
verbatimTextOutput("a_b")
)
)
))
server <- function(input, output, session){
output$bUI <- renderUI({
numericInput("b", "B", 3)
})
safe_b <- eventReactive(input$b, if(isTruthy(input$b)) input$b else 3, ignoreNULL = F)
output$a_b <- renderPrint(input$a * safe_b())
}
shinyApp(ui = ui, server = server)
I have the shiny app below with 2 actionButton(). I want when I press Datatable the Datatable2 to be disabled and when I click again on Datatable the Datatable2 to be available for pressing again.
library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("exc","Datatable"),
actionButton("exc2","Datatable2")
),
mainPanel(
)
)
)
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
This is really straightforward if you use the toggleState() function from the shinyjs package.
The help for that function gives you an extremely similar situation. In your case:
library(shiny)
ui <- fluidPage(
useShinyjs(), #this activates shinyjs
sidebarLayout(
sidebarPanel(
actionButton("exc","Datatable"),
actionButton("exc2","Datatable2")
),
mainPanel(
)
)
)
server <- function(input, output) {
observeEvent(input$exc, {
toggleState("exc2") #identify the element to toggle between active/inactive
})
}
shinyApp(ui = ui, server = server)
I have a simple problem with Shiny: I'm using a navbarPage layout, and I have two different sidebars. I want the sidebar to be conditional on which page of the app the user is on.
That seems easy enough, and the following approach works fine at changing the sidebar panel, but with this approach my tab headers drop down from the top navbar and into the main panel. I Have tried various approaches to get them back into the navbar, which all haven't worked.
Suspect there's a very simple solution, any help gratefully received!
library(shiny)
ui <- navbarPage(title = "example",
sidebarLayout(
sidebarPanel(
conditionalPanel(condition = 'input.tabs==1',"sidebar 1"),
conditionalPanel(condition = 'input.tabs==2 | input.tabs==3',"sidebars 2&3")),
mainPanel(tabsetPanel(id="tabs",
tabPanel("About",value=1, "hello 1"),
tabPanel("parameters",value=2, "hello 2"),
tabPanel("outputs",value=3, "hello 3")
))))
server <- function(input, output) {
}
shinyApp(ui = ui, server = server)
You don't need the tabsetPanel to achieve this, just assign the id to the navbarPage itself and see which one is clicked
library(shiny)
ui <- navbarPage(title = "example",
id = 'tabs',
tabPanel("About",value=1, "hello 1"),
tabPanel("parameters",value=2, "hello 2"),
tabPanel("outputs",value=3, "hello 3"),
sidebarPanel(
conditionalPanel(condition = 'input.tabs == 1',"sidebar 1"),
conditionalPanel(condition = 'input.tabs == 2 | input.tabs==3',"sidebars 2&3")
)
)
server <- function(input, output, session) {
observe({
print(input$tabs)
})
}
shinyApp(ui = ui, server = server)