Reputation: 967
I'm a shiny js newbie and seem to be at a stalemate with this issue.
I want to create a dropdown button whose label changes with the user choice from that button.
The following is my minimum reproducible code. I grabbed a dropdown button function from this post: drop-down checkbox input in shiny:
library(shiny)
library(shinyjs)
dropdownButton <- function(label = "", status = c("default", "primary", "success", "info", "warning", "danger"), ..., width = NULL) {
status <- match.arg(status)
# dropdown button content
html_ul <- list(
class = "dropdown-menu",
style = if (is.null(width))
paste0("width: 375px; overflow-y:scroll; max-height: 300px"), # width: validateCssUnit(width)
lapply(X = list(...), FUN = tags$li, style = "margin-left: 10px; margin-right: 10px;")
)
# dropdown button apparence
html_button <- list(
class = paste0("btn btn-", status," dropdown-toggle"),
type = "button",
`data-toggle` = "dropdown"
)
html_button <- c(html_button, list(label))
html_button <- c(html_button, list(tags$span(class = "caret")))
# final result
tags$div(
class = "dropdown",
do.call(tags$button, html_button),
do.call(tags$ul, html_ul),
tags$script(
"$('.dropdown-menu').click(function(e) {
e.stopPropagation();
});")
)
}
ui <- fluidPage(
uiOutput("button")
)
server <- function(input, output) {
output$button <- renderUI({
list(
useShinyjs(),
dropdownButton(label = "Cut Table By:", status = "default",
radioButtons("letters",
NULL,
choices = c("A", "B", "C", "D", "E"),
selected = "B")
)
)
})
}
shinyApp(ui, server)
I'd like the default label to the button to be "Cut Table by" (or it could even be the choice "B") but then when the user chooses another choice, change to that letter.
I think the part that confuses me the most is the radio button function imbedded in the drop down function, and that I somehow need to make an event with an input to the imbedded function that affects an input to the imbedding function. But perhaps the situation is simpler than it seems to me.
Thank you for your help!
Upvotes: 1
Views: 990
Reputation: 9676
You can add any element as label
in your button
tag. So the easiest way would be to make the label a reactive textOutput
which then can react to the chosen radioButton
. This way, you don't even have to change your dropdownButton
function. The additions I made are pretty straightforward. Only mind that the textOutput
must have inline = TRUE
in order to not have an ugly break before the caret.
I modified your given code:
library(shiny)
library(shinyjs)
dropdownButton <- function(label = "", status = c("default", "primary", "success", "info", "warning", "danger"), ..., width = NULL) {
status <- match.arg(status)
# dropdown button content
html_ul <- list(
class = "dropdown-menu",
style = if (is.null(width))
paste0("width: 375px; overflow-y:scroll; max-height: 300px"), # width: validateCssUnit(width)
lapply(X = list(...), FUN = tags$li, style = "margin-left: 10px; margin-right: 10px;")
)
# dropdown button apparence
html_button <- list(
class = paste0("btn btn-", status," dropdown-toggle"),
type = "button",
`data-toggle` = "dropdown"
)
html_button <- c(html_button, list(label))
html_button <- c(html_button, list(tags$span(class = "caret")))
# final result
tags$div(
class = "dropdown",
do.call(tags$button, html_button),
do.call(tags$ul, html_ul),
tags$script(
"$('.dropdown-menu').click(function(e) {
e.stopPropagation();
});")
)
}
ui <- fluidPage(
uiOutput("button")
)
server <- function(input, output) {
output$button <- renderUI({
list(
useShinyjs(),
dropdownButton(label = textOutput("labels", inline = TRUE), status = "default",
radioButtons("letters",
NULL,
choices = c("A", "B", "C", "D", "E"),
selected = "B")
)
)
})
output$labels <- renderText(paste("Cut Table By:", input$letters))
}
shinyApp(ui, server)
Upvotes: 2