0

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)
John Smith
  • 1,604
  • 4
  • 18
  • 45
  • 1
    Hmm. Looks to me like you don't decrement `rv$value` when you delete a UI element. And you have only one module controller (in `newline`) in your main server. You need a separate module controller for each instance of your module UI. So put them in an array and manage them there. Sort those things out, and if you still have issues, we may be able to do more to help. The second revision to my answer to [this post](https://stackoverflow.com/questions/62341353/saving-dynamic-ui-to-global-r-workspace/62342118#62342118) demonstrates one approach you could use. – Limey Jun 20 '20 at 09:11
  • Hi Limey, I am struggling to understand the whole thing... when deleting a UI element, I don't decrement `rv$value` because I want to keep the initial variable numbers. For example, if I have: 1, 2, then 2 is deleted, when adding another one, we can name it 3. Then then the global deletion, I want to reinitialise `rv$value` but I don't understand why the previous actions of individuel deletion still (seem to) have effect... – John Smith Jun 21 '20 at 22:45

0 Answers0