问题
Is it possible to add dynamically a new item in a shiny accordion, for example when clicking on a button ?
below a non-working example using dq_accordion from the dqshiny package
Thanks !
library(shiny)
library(dqshiny)
shinyApp(
ui = fluidPage(
fluidRow(
actionButton("add", "+"),
dq_accordion("myAccordion",
titles = paste0("input",1:3),
contents = list(textInput(inputId = "txt1",
label = ""),
textInput(inputId = "txt2",
label = ""),
textInput(inputId = "txt3",
label = "")),
bg_color = NULL,
options = list(animate = 200, collapsible = TRUE),
icons = c(open = "hand-point-down", closed = "hand-point-right")),
actionButton("delete", "-")
)
),
server = function(input, output) {
observeEvent(input$add, {
# how to add a new item in myAccordion ?
})
observeEvent(input$delete, {
# how to delete a new item in myAccordion ?
})
}
)
回答1:
I have a solution with modules and with the function render_dq_box_group, I think this is what you're trying to do:
library(shiny)
library(dqshiny)
selectorUI <- function(id){
ns = NS(id)
tags$div(
fluidRow(
column(6, uiOutput(ns('new_ui')))
),
id = paste0('ui', id)
)
}
selectorServer <- function(input, output, session){
ns = session$ns
output$new_ui <- render_dq_box_group({
dq_accordion(ns("foo"),
titles = ns("input"),
contents = list(textInput(inputId = ns("txt"),
label = "")),
bg_color = NULL,
options = list(animate = 200, collapsible = TRUE),
icons = c(open = "hand-point-down", closed = "hand-point-right")
)
})
}
shinyApp(
ui = fluidPage(
fluidRow(
actionButton("add", "+"),
selectorUI(1),
selectorUI(2),
selectorUI(3),
tags$div(id = 'placeholder'),
actionButton("delete", "-")
)
),
server = function(input, output) {
callModule(selectorServer, 1)
callModule(selectorServer, 2)
callModule(selectorServer, 3)
counter <- reactiveValues(value = 3) # number of inputs already present
observeEvent(input$add, {
counter$value <- counter$value + 1
insertUI(
selector = "#placeholder",
ui = selectorUI(counter$value)
)
callModule(selectorServer, counter$value)
})
observeEvent(input$delete, {
removeUI(
selector = paste0("#ui", counter$value)
)
counter$value <- counter$value - 1
})
}
)
I used this answer to make this solution.
回答2:
I switched to tabsetPanel and the appendTab/removeTab functions. It is working flawlessly but it is not an accordion so not exactly the behavior I would like in my shiny app...
here is the solution with tabsetPanel :
library("shiny")
ui <- shinyUI(
fluidPage(
fluidRow(
actionLink("add", "add"),
tabsetPanel(id="tab", type="pills"),
actionLink("delete", "delete")
)
))
server <- shinyServer(function(input, output) {
# initialization
counter <- reactiveVal(0)
observeEvent(input$delete, {
# remove current (input$tab contains the current tabPanel)
removeTab("tab", target=input$tab)
})
observeEvent(input$add, {
counter(counter() + 1) # set the counter
# add a new input
appendTab(inputId = "tab",
tab = tabPanel(title = paste0("input", counter()),
textInput(inputId = paste0("input", counter()),
label = paste0("input", counter()))
),
select=TRUE)
})
})
shinyApp(ui, server)
来源:https://stackoverflow.com/questions/60039314/is-it-possible-to-add-dynamically-a-new-item-in-a-shiny-accordion