I have one selectizeInput and one fileInput in my shiny app.
I want to keep fileInput disabled until some value is not selected in selectizeInput.
Also I want a popup message to select a value every time user clicks on fileInput.
How can I do that.
As others have mentioned, the shinyjs package is useful here. You could use enable, disable, or toggleState.
library(shiny)
library(shinyjs)
ui = fluidPage(
shinyjs::useShinyjs(),
selectizeInput("selector", label="Choose 2:", multiple=TRUE,
choices=letters[1:5], selected=letters[1:5]),
fileInput("file_inputer", label="upload file")#,
# dataTableOutput('table')
)
server = function(input, output) {
observe({
shinyjs::toggleState("file_inputer", length(input$selector) %in% 0:4)
})
observeEvent(input$file_inputer, {
showModal(modalDialog(
title="Do you want a header row?",
selectInput("option_selector", label="Choose an option",
choices=c("option 1", "option 2", "option 3")),
footer = tagList(actionButton("read_file", "Read File"),
modalButton("Cancel")
)
))
})
observeEvent(input$read_file, {
# do something with your option value
removeModal()
})
}
# Run the application
shinyApp(ui = ui, server = server)
Related
Below I press the first actionButton() "Show" to display another actionButton() but I would like also a second actionButton() named "Hide" that will hide the actionButton() that is displayed after clicking the "Show".
library(shiny)
ui = shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("button1", label = "Show"),
actionButton("button1b", label = "Hide")
),
mainPanel(
# what should I write here?
uiOutput("button2")
)
)
))
server = shinyServer(function(input, output, session) {
observeEvent(input$button1, {
output$button2 <- renderUI({
actionButton("button2", label = "Press Button 2")
})
})
})
shinyApp(ui = ui, server = server)
One option is to put the second button inside a conditionalPanel and set a toggle to display/hide the panel. See working code below.
library(shiny)
ui = shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("button1", label = "Show"),
actionButton("button1b", label = "Hide")
),
mainPanel(
# what should I write here?
conditionalPanel(condition = "output.display",
actionButton("button2", label = "Press Button 2"))
)
)
))
server = shinyServer(function(input, output, session) {
r <- reactiveValues(
toggle = NULL
)
observeEvent(input$button1, {
r$toggle = 1
})
observeEvent(input$button1b, {
r$toggle = 0
})
output$display <- reactive({
r$toggle
})
outputOptions(output, "display", suspendWhenHidden = FALSE)
})
shinyApp(ui = ui, server = server)
Another option is to dynamically insert and remove UI elements. But that option requires creation/destruction of UI elements every time the buttons are clicked. See example here
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)
how can a person reset the actionButton back to being selected = character(0) rather than one of the radio buttons that they have available,
any idea?
you can use shinyjs package for this,Thanks to Dean Attali for this wonderful package.
This is an example:
if (interactive()) {
library(shiny)
library(shinyjs)
shinyApp(
ui = fluidPage(
useShinyjs(),
div(
id = "form",
textInput("name", "Name"),
radioButtons("gender", "Gender", c("Male", "Female"))
),
actionButton("resetAll", "Reset all"),
actionButton("resetName", "Reset name"),
actionButton("resetGender", "Reset Gender")
),
server = function(input, output) {
observeEvent(input$resetName, {
reset("name")
})
observeEvent(input$resetGender, {
reset("gender")
})
observeEvent(input$resetAll, {
reset("form")
})
}
)
}
You can read about this in here
To my knowledge it is impossible to reset an actionButton in shiny.
You can consider incrementing a reactiveValue each time the button is clicked, and then checking if this value is odd or even to perform a given action.
Are you trying to use an action button to reset a radio button? Try using updateRadioButton (https://shiny.rstudio.com/reference/shiny/0.14/updateRadioButtons.html). Here is an example:
library("shiny")
ui <- fluidPage(
sidebarPanel(
radioButtons("radio_buttons", "Radio buttons", list("option 1", "option 2"),
selected = character(0)),
actionButton("reset_button", "Reset button")
)
)
server <- function(input, output, session) {
observeEvent(input$reset_button, {
updateRadioButtons(session, "radio_buttons", "Radio buttons", list("option 1", "option 2"),
selected = character(0)
)
})
}
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)
I'm implementing a drill down in my app so that when user clicks on a data table new tab is opened showing details for the selected cell. I wanted to add auto bookmarking (url updates itself) to my app so I can send a link to a specific, newly generated tab but the tab is not restored correctly. I think the observer is not triggered during the restoration process. Any ideas on how to make it work?
Minimal example:
library(shiny)
library(DT)
library(shinydashboard)
ui <- function(request) {
dashboardPage(
dashboardHeader(title = "Drilldown not restoring"),
dashboardSidebar(disable = T),
dashboardBody(
tabsetPanel(id = "tabs",
tabPanel("Cars overview",
h1("Cars overview"),
div("Click any cell"),
br(),
DT::dataTableOutput("mtcars")
)
)
)
)
}
server <- function(input, output, session) {
# Generate data table
output$mtcars <- DT::renderDataTable({mtcars})
# Observe when row is selected and open new tab
observeEvent(input$mtcars_rows_selected, {
print("Trigger")
appendTab(inputId = "tabs",
tabPanel(
"Car details",
"Car detail info"
)
)
# Focus on newly created tab
updateTabsetPanel(session, "tabs", selected = "Car details")
})
# Enable bookmarking
observe({
reactiveValuesToList(input)
session$doBookmark()
})
onBookmarked(function(url) {
updateQueryString(url)
})
}
shinyApp(ui, server, enableBookmarking = "url")