Updating the InsertUI elements

...
Suppose I have a Data frame as given below and I created multiple panels using the insert UI elements. How do I, in my case update the values in these multiple panels.

I could update the inputs for the first panel but things get messier as I try to update the other added panels. Suppose in one panel I need data for Earthquake in 1985 and in the other panel I need data for Earthquake in 1990.

How do I do that? For the first panel it works fine and I could toggle between 1985 and 1990 data, but as I add new panel the updates doesn't work accordingly in any of the panels including the first one.

Also the the position of delete button not changing left or right with CSS commands, WHY?

Any help from anyone is appreciated as R is a bit getting difficult for me.

Here is the code I tried working on but without success

     # Demo dataframe

 DT <- data.frame(Year = c(1980,1985,1985,1990,1990,1995), 
                  Events = c("Storm","Earthquake","Flood","Draught","Earthquake","Flood"),
                 Area_Loss = c(100, 200, 400, 500, 450,300),
                 Money =  c(1000,2000,3000,4000,5000,6000))


    #UI Logic 

    ui <- fluidPage( h4("Updating InserUIs",
                     inlineCSS("#delete_div{margin-top:1em;}"),
      
        selectInput("events","Events",choices = as.character(DT$Events)),
        tags$div(id = "Panels"),
        actionButton("add","Add")    
       ))


  #Server Logic 

 server <- function(session, input, output){

   vals <- reactiveValues(btn = 0)

 #Adding and Removing buttons 

 observeEvent(input$add,ignoreNULL = FALSE,{

    vals$btn <- vals$btn +1

insertUI(

  selector = "#Panels",
     ui = splitLayout(id = paste0("Selection",vals$btn), where = "afterEnd",
                                   cellWidths = rep("33.33%",3),

    selectInput(paste("year",vals$btn +1,sep = ""), "Year", 
                  choices = as.numeric(DT$Year), selected = ""),
    
    numericInput(paste("area",vals$btn +1,sep = ""), "Area", min = 0, max = 10000,
                           value ="", step = 1),
   numericInput(paste("money",vals$btn +1,sep = ""), "Money", min = 0, max  = 10000,
                           value = "", step =1),
    
  div(id = "delete_div",actionButton(paste0("delete",vals$btn),  "Delete"))))
    

        observeEvent(input[[paste0("delete",vals$btn)]],{
                   shiny::removeUI(selector = paste0("#Selection",vals$btn))
                    vals$btn <- vals$btn - 1

   })
 })

       #For Updating the inserted UIs

                Year_Value <- reactive({
                     Year <- c(input[["year"]])
                              if(vals$btn>0){
                                  for(i in 1:vals$btn){
                     Year <- c(Year,input[[paste0("year", i+1)]])
                }
              Year <- paste(Year,collapse = "\n")     
        }
      })

        #Updates based on Year and Events

     observeEvent(input$events,
     updateSelectInput(session,paste("year",vals$btn +1,sep =   ""), "Year",
              choices = as.numeric(DT$Year)[DT$Events == input$events], selected = ""))


    observeEvent(Year_Value(),
           updateNumericInput(session,paste("area",vals$btn +1,sep = ""),
               "Area",min= 0, max= 50000,value = DT$Area_Loss[DT$Year ==  Year_Value() &
                          DT$Events== input$events] ,step = 0.1))

   observeEvent(Year_Value(),
          updateNumericInput(session,paste("money",vals$btn +1,sep = ""),
             "Money",min= 0, max= 50000,value = DT$Money[DT$Year ==    Year_Value()  &
              DT$Events == input$events],step = 0.1))

 }

    shinyApp(ui,server)

I want my updates to work properly for all the inserted ui elements. I will be extremely grateful to anyone contributing towards solving my problem. I am looking for any kind of help in this regard.

I searched for this particular topic for quite a few days but didn't get anything on it. The task should have been a trivial one but it is not straightforward as I thought it would be. I hope that R studio community can help me this regard which is quite an urgent for me and I have already spent quite a lot of time on it

Thanks in advance.

Start by creating a reproducible example.

When I run your code I get:

Error in fluidPage(h4("Updating InserUIs", inlineCSS("#delete_div{margin-top:1em;}"),  : 
  could not find function "fluidPage"

(obviously I know how to fix this but it suggests that there will be other problems along the way)

Thanks a lot for the reply and sorry for the error. I didn't write the lines for libraries and that's I think is the error. I am updating my code example with some additional problem that I have encountered while going further with the App.

I have kind of partially worked out a solution for the update part which I am including in my example. But I am not sure whether this is the right way to do it.

Additionally I have to update a text output based on the newly added insertUIs. What my code is doing right now is the following

  • For the first input panel the update is fine but adding panels doesn't make the update to work smoothly (Screenshot in PDF formPanel_Problems.pdf (139.3 KB) provided to explain the situation).

  • The text output is coming individually with addition of UI elements but the value changes to last user input for all the UI elements (Screenshot in PDF form provided to explain the situation).

       library(shiny)
       library(tidyverse)
    
           DT <- data.frame(Year = c(1980,1985,1985,1990,1990,1995), 
               Events = c("Storm","Earthquake","Flood","Draught","Earthquake","Flood"), 
               Area_Loss = c(100, 200, 400, 500, 450,300), 
               Money = c(1000,2000,3000,4000,5000,6000))
    
          ui <- fluidPage( h4("Updating InserUIs",
                  inlineCSS("#delete_div{margin-top:1em;}"),
                  selectInput("events","Events",choices = as.character(DT$Events)),
                  tags$div(id = "Panels"),
                  actionButton("add","Add"),
                  tableOutput("table")
              ))
          
    
      server <- function(session, input, output){
    
      # Reactive values for the number of input panels
    
     vals <- reactiveValues(btn = 0)
    
     observeEvent(input$add,ignoreNULL = FALSE,{
    
     vals$btn <- vals$btn +1
    
      # Add Panels  
    
     insertUI(
       selector = "#Panels",
         ui = splitLayout(id = paste0("Selection",vals$btn), where = "afterEnd",
                     cellWidths = rep("25%",4),
                     selectInput(paste("year",vals$btn +1,sep = ""), "Year", DT$Year, selected = ""),
                                              
                     numericInput(paste("area",vals$btn +1,sep = ""), "Area", min = 0, max = 10000, 
                                                    value ="", step = 1),
                     numericInput(paste("money",vals$btn +1,sep = ""), "Money", min = 0, max = 
                                                     10000, value = "", step =1),
                     textOutput(paste("text",vals$btn+1,sep = "")),
                     div(id = "delete_div",actionButton(paste0("delete",vals$btn), "Delete"))))
    
       # Delete  Panels
    
         observeEvent(input[[paste0("delete",vals$btn)]],{
    
         shiny::removeUI(selector = paste0("#Selection",vals$btn))
         vals$btn <- vals$btn - 1
    
         })
       })
    
      # Year value for updating the inserted UIs
    
     Year_Value <- reactive({
    
        if(vals$btn>0){
            for(i in 1:vals$btn){
              Year <- c(input[[paste0("year", i+1)]])
      }
        Year <- c(Year)
     }
     })
    
    
       # Updation based on Year and Events
    
        observeEvent(input$events,
             updateSelectInput(session,
                               paste("year",vals$btn +1,sep = ""),
                               "Year", choices = as.numeric(DT$Year)
                               [DT$Events == input$events], selected = ""))
    
    
        observeEvent(Year_Value(),
             updateNumericInput(session,
                                paste("area",vals$btn +1,sep = ""),
                                "Area",min= 0, max= 50000,value = DT$Area_Loss
                                [DT$Year == Year_Value() & DT$Events== input$events] ,step = 0.1))
    
        observeEvent(Year_Value(),
             updateNumericInput(session,
                                paste("money",vals$btn +1,sep = ""),
                                "Money",min= 0, max= 50000,
                                value = DT$Money[DT$Year == Year_Value() & DT$Events == 
                                input$events],step = 0.1))
    
       # Reactive table generated from the user inputs
    
        Table <- reactive({
    
      Year <- c(input[["year"]])
     Area_Loss <- c(input[["area"]])
     Money <- c(input[["money"]])
         if(vals$btn>0){
           for(i in 1:vals$btn){
               Year <- c(Year,input[[paste0("year", i+1)]])
              Area_Loss <- [Panel_Problems.pdf|attachment](upload://tqpsbT2QLd8rTnWoV74Pg9Vqcaj.pdf) (139.3 KB) c(Area_Loss,input[[paste0("area", i+1)]])
             Money <- c(Money,input[[paste0("money", i+1)]])
        }
           Year <- c(Year)
           Area_Loss <- c(Area_Loss)
           Money <- c(Money)
    
        DF0 <- data.frame(Events = input$events, 
                            Year = as.numeric(as.character(Year)), 
                            Area_Loss =  as.numeric(as.character(Area_Loss)),
                            Money =  as.numeric(as.character(Money)))
    
       DF1 <- DF0%>%
                 drop_na()
    
              print(DF1)  
        }
    
       })
    
            # Updating the textoutputs (can be used for displaying certain calculations as well)
    
                     observe({
    
                            output[[paste("text",vals$btn+1,sep = "")]] <- renderText({
    
                                  input[[paste("money",vals$btn +1,sep = "")]]
    
                  })
             })
    
              # Visualizing the raective table
    
                  output$table <- renderTable({
    
                          Table()
    
            })
    
       }
    
       shinyApp(ui,server)
    

Additionally I will be extremely grateful to you if you could tell me that how to use my insertUI ids generated in my code for CSS style sheets which I will highlight it below

         numericInput(inputId = paste("money",vals$btn +1,sep = ""), "Money", min = 0, max = 
                              10000, value = "", step =1)

Which comes something like below in the HTML page and is dynamic in nature

         money2(first panel), money3(second panel) etc...

How do I deal something like this in my style sheet.

When I attempt to run that code, I get:

Error: unexpected '[' in:
"           Year <- c(Year,input[[paste0("year", i+1)]])
          Area_Loss <- ["
[

Sorry my bad, The PDF link got inside the code lines and that's why the error. I made a mistake while uploading my PDF link.

I am again uploading the code, it will run for sure now

   library(shiny)
   library(tidyverse)

       DT <- data.frame(Year = c(1980,1985,1985,1990,1990,1995), 
             Events = c("Storm","Earthquake","Flood","Draught","Earthquake","Flood"), 
             Area_Loss = c(100, 200, 400, 500, 450,300), 
             Money = c(1000,2000,3000,4000,5000,6000))

       ui <- fluidPage( h4("Updating InserUIs",
                inlineCSS("#delete_div{margin-top:1em;}"),
                selectInput("events","Events",choices = as.character(DT$Events)),
                tags$div(id = "Panels"),
                actionButton("add","Add"),
                tableOutput("table")
       ))


 server <- function(session, input, output){

      # Reactive values for the number of input panels

     vals <- reactiveValues(btn = 0)

     observeEvent(input$add,ignoreNULL = FALSE,{

     vals$btn <- vals$btn +1

     # Add Panels  

    insertUI(
      selector = "#Panels",
      ui = splitLayout(id = paste0("Selection",vals$btn), where = "afterEnd",
                      cellWidths = rep("25%",4),
                      selectInput(paste("year",vals$btn +1,sep = ""), "Year", DT$Year, selected = ""),
                   
                      numericInput(paste("area",vals$btn +1,sep = ""), "Area", min = 0, max = 
                                    10000,   value ="", step = 1),
                              
                     numericInput(paste("money",vals$btn +1,sep = ""), "Money", min = 0, max = 
                                  10000, value = "", step =1),
                      textOutput(paste("text",vals$btn+1,sep = "")),
                       div(id = "delete_div",actionButton(paste0("delete",vals$btn), "Delete"))))

       # Delete  Panels

     observeEvent(input[[paste0("delete",vals$btn)]],{
  
         shiny::removeUI(selector = paste0("#Selection",vals$btn))
              vals$btn <- vals$btn - 1
  
   })
  })

   # Year value for updating the inserted UIs

    Year_Value <- reactive({

       if(vals$btn>0){
          for(i in 1:vals$btn){
             Year <- c(input[[paste0("year", i+1)]])
        }
         Year <- c(Year)
      }
   })


     # Updation based on Year and Events

       observeEvent(input$events,
                   updateSelectInput(session,
                                 paste("year",vals$btn +1,sep = ""),
                                 "Year", choices = as.numeric(DT$Year)
                                  [DT$Events == input$events], selected = ""))


      observeEvent(Year_Value(),
                  updateNumericInput(session,
                                 paste("area",vals$btn +1,sep = ""),
                                   "Area",min= 0, max= 50000,value = DT$Area_Loss
                                    [DT$Year == Year_Value() & DT$Events== input$events] ,step = 0.1))

      observeEvent(Year_Value(),
                updateNumericInput(session,
                                paste("money",vals$btn +1,sep = ""),
                                 "Money",min= 0, max= 50000,
                                    value = DT$Money[DT$Year == Year_Value() & DT$Events == 
                                                    input$events],step = 0.1))

   # Reactive table generated from the user inputs

      Table <- reactive({

      Year <- c(input[["year"]])
      Area_Loss <- c(input[["area"]])
      Money <- c(input[["money"]])
     if(vals$btn>0){
         for(i in 1:vals$btn){
            Year <- c(Year,input[[paste0("year", i+1)]])
            Area_Loss <- c(Area_Loss,input[[paste0("area", i+1)]])
           Money <- c(Money,input[[paste0("money", i+1)]])
      }
        Year <- c(Year)
  Area_Loss <- c(Area_Loss)
  Money <- c(Money)
  
       DF0 <- data.frame(Events = input$events, 
                    Year = as.numeric(as.character(Year)), 
                    Area_Loss =  as.numeric(as.character(Area_Loss)),
                    Money =  as.numeric(as.character(Money)))
  
       DF1 <- DF0%>%
        drop_na()
  
       print(DF1)  
    }

   })

   # Updating the textoutputs (can be used for displaying certain calculations as well)

   observe({

       output[[paste("text",vals$btn+1,sep = "")]] <- renderText({
  
       input[[paste("money",vals$btn +1,sep = "")]]
  
      })
  })

     # Visualizing the raective table

        output$table <- renderTable({

                 Table()

     })

  }

   shinyApp(ui,server)

I have re- checked, it is working now. Sorry, for the inconvenience

Thanks

Jitu

Hi,
I am replying you regarding review of my code. I am curios to know the mistakes I have made in my code and what is the right approach.

Thanks

Jitu

I still can't run it. I now get:

Error in inlineCSS("#delete_div{margin-top:1em;}") : 
  could not find function "inlineCSS"

At this point, I have spent as much time attempting to help you as I can spare.

But it is running in my system and I believe that removing the CSS command will run the code.

At least can you point me in a direction where I can look into this matter. My problem is also well documented in the pdf I uploaded.

It is something to do with the first panel being disabled after I add a second panel and so on. Any little help is highly appreciated.

Thanks

Jitu