when I click the selection everytime, the drop download box close automaticlly.
Please how to keep the drop box open ?
Great Thanks
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
dropdownButton(
label="Close after click",
style = "unite",
icon = icon("gear"),
multiInput('test','test',choices = letters)
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
Related
In order to make an app where panels are created dynamically, I would like to remove, hide and/or update panels from the package shinyWidgets.
I didn't find any function to do so nor way to add IDs to these panel.
If you have the solution or a way around, I would be more than happy. Thank you in advance !
library(shiny)
library(shinyWidgets)
ui <- fluidPage(
panel(
heading = "Test panel",
actionButton("remove_panel", "Remove this panel")
)
)
server <- function(input, output) {
observeEvent(input$remove_panel,{
print("remove panel")
})
}
shinyApp(ui = ui, server = server)
There is no official method you can use to change the panel states, but we can do it with custom expressions.
library(shiny)
library(shinyWidgets)
library(shinyjs)
ui <- fluidPage(
useShinyjs(),
panel(
heading = "Test panel1",
id = "test_panel1",
actionButton("remove_panel", "Remove this panel")
),
panel(
heading = "Test panel2",
id = "test_panel2",
"some content"
),
actionButton("hide_panel", "Hide this panel")
)
server <- function(input, output) {
observeEvent(input$remove_panel,{
removeUI('.panel:has([id="test_panel1"])', immediate = TRUE)
})
observeEvent(input$hide_panel,{
toggle(selector = '.panel:has([id="test_panel2"])')
if(input$hide_panel %% 2 == 1) return(updateActionButton(inputId = "hide_panel", label = "Show this panel"))
updateActionButton(inputId = "hide_panel", label = "Hide this panel")
})
}
shinyApp(ui = ui, server = server)
To remove:
add an ID argument to your panel, and use removeUI to remove it. Remember to change the ID in you own case.
To hide/show:
We can use toggle from shinyjs to show or hide some elements we choose.
Use updateActionButton to also change it text when hidden.
I have two modals. When the first is opened, the background should be grayed out, as is default. But this should not happen with the second one. The code is:
library(shiny)
ui <- fluidPage(
tags$style(type = 'text/css', '.modal-backdrop { display: none }'),
actionButton('modal1', 'Modal1'),
actionButton('modal2', 'Modal2'),
)
server <- function(input, output) {
observeEvent(input$modal1,
showModal(modalDialog(title = "Modal1"))
)
observeEvent(input$modal2,
showModal(modalDialog(title = "Modal2"))
)
}
shinyApp(ui = ui, server = server)
The css code should be connected to the id of the second modal dialog, but it is not possible to include an id in the function 'modalDialog'.
Any ideas about how to apply the css code selectively to only the second modal?
You can add JS code to hide the backdrop after showing the second modal using tags$script just after modalDialog.
library(shiny)
ui <- fluidPage(
actionButton('modal1', 'Modal1'),
actionButton('modal2', 'Modal2'),
)
server <- function(input, output) {
observeEvent(input$modal1,
showModal(modalDialog(title = "Modal1"))
)
observeEvent(input$modal2, {
showModal(
list(
modalDialog(title = "Modal2"),
tags$script("$('.modal-backdrop').css('display', 'none');")
)
)
})
}
shinyApp(ui = ui, server = server)
I have a server generated sidebar. After its creation, I want to hide its first element. The observer doing the hiding is executed, however, the menuitem is not hidden. I am trying to figure out, why it does not work. Any thoughts?
PS. The CSS selector appears to be correct, as all works when the UI is not created on the server.
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
uiOutput("sidebar_ui")
),
dashboardBody(
shinyjs::useShinyjs()
)
)
server <- function(session, input, output)
{
rv <- reactiveValues()
output$sidebar_ui <- renderUI({
rv$trigger_sidebar_config <- 0
cat("\nSidebar create")
sidebarMenu(id = "sidebar",
menuItem("Menu1", tabName = "tab_menu_1"), # to be hidden
menuItem("Menu2", tabName = "tab_menu_2") )
})
observeEvent(rv$trigger_sidebar_config, {
cat("\nSidebar config")
shinyjs::hide(selector = '[data-value="tab_menu_1"]') # hide menuitem
})
}
shinyApp(ui, server)
Your observeEvent is executed too early because the reactive value trigger_sidebar_config is updated during the same cycle as renderUI. Accordingly shiny tries to hide an UI element which isn't existing yet (you would have to wait for the UI beeing rendered, instead of it's calculation beeing triggered, for this to work).
You can test this e.g. via delaying the execution of shinyjs::hide - it works when triggered by an actionButton (Please see my below example) or you have a look at the reactlog:
Here you can see, that the observeEvent triggered via trigger_sidebar_config finished calculating after 3ms but the sidebar wasn't ready at this time (30ms).
If you want the tab to be hidden on startup you can use hidden() in your renderUI call (see Menu3):
library(shiny)
library(shinyjs)
library(shinydashboard)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
uiOutput("sidebar_ui")
),
dashboardBody(
shinyjs::useShinyjs(),
actionButton("hide", "hide tab")
)
)
server <- function(session, input, output)
{
rv <- reactiveValues()
output$sidebar_ui <- renderUI({
rv$trigger_sidebar_config <- 0
cat("\nSidebar create")
sidebarMenu(id = "sidebar",
menuItem("Menu1", tabName = "tab_menu_1"), # to be hidden
menuItem("Menu2", tabName = "tab_menu_2"),
shinyjs::hidden(menuItem("Menu3", tabName = "tab_menu_3")))
})
observeEvent(input$hide, {
cat("\nSidebar config")
shinyjs::hide(selector = '[data-value="tab_menu_1"]') # hide menuitem
})
}
shinyApp(ui, server)
In this context please also see ?renderMenu().
I am using Shiny with the Shiny Semantic library to make the app look nice. The standard Shiny pop-up message using showModal(modalDialog()) doesn't work with Semantic UI, so I have resorted to shinyjs to use some javascript to allow modals. With a js modal defined globally, how do I integrate a datatable into the modal? Here is a minimal example:
library(shiny)
library(shinyjs)
library(shiny.semantic)
library(DT)
modal.js = "$('.ui.modal')
.modal('show')
;"
server <- function(input, output, session) {
output$my_table = DT::renderDataTable({
head(iris)
})
observeEvent(input$open_modal, {
runjs(modal.js)
})
}
ui <- semanticPage(
suppressDependencies("bootstrap"),
useShinyjs(),
div(class = "ui modal",
div(class="header", 'Modal header'),
p('Placing DT::dataTableOutput("my_table") here fails.
If it was displayed, I would select a row and return the value to a reactiveValue.')
),
div(class = "ui basic button action-button", id = "open_modal", "Open modal ui"),
div(class = "ui raised segment", DT::dataTableOutput("my_table"))
)
shinyApp(ui, server, options = list(launch.browser = TRUE))
I've had the same issue today and managed to find a way to resolve this. When the modal opens in shiny.semantic the datatable output is still classed as not visible. To fix this you just need to add in an extra line to the JavaScript:
$('#my_table').show().trigger('shown');
You'll need to add some more JS if you want to hide it again when closed, but that might be better in the UI using tags$script() instead of in the server.
Updated app:
library(shiny)
library(shinyjs)
library(shiny.semantic)
library(DT)
modal.js <- "$('.ui.modal').modal('show');
$('#my_table').show().trigger('shown');"
server <- function(input, output, session) {
output$my_table = DT::renderDataTable(head(iris))
observeEvent(input$open_modal, runjs(modal.js))
}
ui <- semanticPage(
suppressDependencies("bootstrap"),
useShinyjs(),
div(
class = "ui modal",
div(class = "header", "Modal header"),
div(class = "content", div(class = "ui raised segment", DT::dataTableOutput("my_table")))
),
div(class = "ui basic button action-button", id = "open_modal", "Open modal ui")
)
shinyApp(ui, server, options = list(launch.browser = TRUE))
Put in your dataTableOutput
output$my_table = DT::renderDataTable({
datatable(head(iris), class = "compact", escape = FALSE) })
I'm trying to write a simple shiny app with an actionButton. When the actionButton is pressed, some text output should be printed directly below. The code below takes me part way to a solution:
shinyApp(
ui = shinyUI( fluidPage(
actionButton("button", "don't press the button"),
verbatimTextOutput("text")
)
),
server = function(input, output, session){
observeEvent(input$button, {
output$text <- renderText({"ahh you pressed it"})
})
}
)
There are two things I'd like to change, but not sure how:
1) The code above shows an empty gray box before the button is pressed - I'd like there to be nothing there prior to the button being pressed. It looks like conditionalPanel might be the right approach, but not sure how to implement this.
2) Can the above code be adapted so that once the button is pressed a second time, the text output is hidden again?
You can try this with shinyjs, hidden and toggle
library(shiny)
library(shinyjs)
shinyApp(
ui = shinyUI(fluidPage(useShinyjs(),
actionButton("button", "don't press the button"),
hidden(
div(id='text_div',
verbatimTextOutput("text")
)
)
)
),
server = function(input, output, session){
observeEvent(input$button, {
toggle('text_div')
output$text <- renderText({"ahh you pressed it"})
})
}
)