Shiny: insert/remove UI, individually and globally

喜夏-厌秋 提交于 2020-06-29 03:41:59

问题


The following shiny code allows us to insert and remove UI individually. The question about removing individually the UI elements was answered here.

Then I wanted to delete all inserted UI in a global manner. And I found a useful answer here.

So there are two actions of deletion, you can see them in the code with the comments

  • Individual deletion: it will delete the nth UI added.
  • Global deletion: the idea is to "reinitialize" the app. For my app, I will just use the action of changing tabs to trigger the deletion of all inserted UI.

With the following code, for me, it should work.

But something very strange happened. When running the app, please follow these steps:

  • Select some value, for example, X1 for Variable 1.
  • Then click on "Add another line" button to add Variable 2 and you can choose X2.
  • Repeat the previous action 3 more times. For each Variable n, choose Xn.
  • Now you can delete Variable 2 and Variable 3 for example.
  • Then change the tabs. By doing so, the remaining Variable 4 and the UI element will be deleted.
  • You can see only one line left. And that is what I wanted: reinitializing the UI and the data.frame. We can then do new selections. But ...
  • When you click on "Add another line", nothing happens.
  • You have to click 3 times, and for the third time, you see the 4th variable appears.

I can't figure why.

>     library(shiny)
>     
>     
>     LHSchoices <- c("X1", "X2", "X3", "X4")
>     
>     
>     #------------------------------------------------------------------------------#
>     
>     # MODULE UI ----
>     variablesUI <- function(id, number) {
>       
>       ns <- NS(id)
>       
>       tagList(
>         div(id = id,
>             fluidRow(
>               column(6,
>                      selectInput(ns("variable"),
>                                  paste0("Select Variable ", number),
>                                  choices = c("Choose" = "", LHSchoices)
>                      )
>               ),
>               
>               column(3,
>                      numericInput(ns("value.variable"),
>                                   label = paste0("Value ", number),
>                                   value = 0, min = 0
>                      )
>               ),
>               column(3,
>                      actionButton(ns("rmvv"),"Remove UI")
>               ),
>             )
>         )
>       )
>       
>     }
>     
>     #------------------------------------------------------------------------------#
>     
>     # MODULE SERVER ----
>     
>     variables <- function(input, output, session, variable.number){
>       reactive({
>         
>         req(input$variable, input$value.variable)
>         
>         # Create Pair: variable and its value
>         df <- data.frame(
>           "variable.number" = variable.number,
>           "variable" = input$variable,
>           "value" = input$value.variable,
>           stringsAsFactors = FALSE
>         )
>         
>         return(df)
>         
>       })
>     }
>     
>     #------------------------------------------------------------------------------#
>     
>     # Shiny UI ----
>     
>     ui <- fixedPage(
>       tabsetPanel(type = "tabs",id="tabs",
>                   tabPanel("t1",value="t1"),
>                   tabPanel("t2",value="t2")),
>       
>       variablesUI("var1", 1),
>       h5(""),
>       actionButton("insertBtn", "Add another line"),
>       
>       verbatimTextOutput("test1"),
>       tableOutput("test2"),
>       
>     
>     )
>     
>     # Shiny Server ----
>     
>     server <- function(input, output,session) {
>       
>       add.variable <- reactiveValues()
>       add.variable$df <- data.frame("variable.number" = numeric(0),
>                                     "variable" = character(0),
>                                     "value" = numeric(0),
>                                     stringsAsFactors = FALSE)
>       
>       var1 <- callModule(variables, paste0("var", 1), 1)
>       
>       observe(add.variable$df[1, ] <- var1())
>       
>       rv <- reactiveValues(value = 0)
>       
>       observeEvent(input$insertBtn, {
>         
>         btn <- rv$value + 1
>         rv$value <- btn
>         
>         insertUI(
>           selector = "h5",
>           where = "beforeEnd",
>           ui = tagList(
>             variablesUI(paste0("var", btn), btn)
>           )
>         )
>         
>         newline <- callModule(variables, paste0("var", btn), btn)
>         
>         observeEvent(newline(), {
>           add.variable$df[btn, ] <- newline()
>         })
>         
>         # individual deletion
>         
>         observeEvent(input[[paste0("var", btn,"-rmvv")]], {
>           removeUI(
>             selector = paste0("#var", btn)
>           )
>         })
>         
>         
>       })
>       
>       # global deletion
>       observeEvent(input$tabs, {
>         print("change")
>         
>         print(rv$value)
>         
>         if (rv$value >1){
>           for (bb in 2:rv$value){
>             removeUI(
>               selector = paste0("#var", bb)
>             )
>             
>           }
>           add.variable$df[1:(rv$value), ]=NA
>         }
>         
>         
>         rv$value=1
>         
>       })
>       
>       
>       output$test1 <- renderPrint({
>         print(add.variable$df)
>       })
>       
>       output$test2 <- renderTable({
>         add.variable$df
>       })
>       
>     }
>     
>     #------------------------------------------------------------------------------#
>     
>     shinyApp(ui, server)

来源:https://stackoverflow.com/questions/62475642/shiny-insert-remove-ui-individually-and-globally

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!