Gaspar Roy
Gaspar Roy

Reputation: 1

Shiny dynamic buttons

I am trying to generate a UI to manage projects in an App. What I do is that each user has his list of projects stored somewhere, and from this list of project I generate, for each project, a div containing four buttons (later buttonTitle, continueProj, deleteProj and shareProj). Each of these buttons, when clicked, is supposed to trigger a function on the corresponding project.

To handle this, each time I get to the panel corresponding to this UI, I empty and generate an UI by project with insertUI, and fill a list for each action.

for (i in 1:(length(list_ui))){
  removeUI(
     selector = paste0('#',i)
   )
}
tit_obsList <<- list()
con_obsList <<- list()
del_obsList <<- list()
sha_obsList <<- list()
list_ui <<- list()

if(length(USER$list_of_projects !=0)){
for (i in 1:length(USER$list_of_projects)){
  insertUI(
    selector = '#placeholder',
    ui = tags$div(
      #class = "ProjectPanel",
      style = "background: #ffffff;
                     display: block; 
                     margin-left: auto; 
                     margin-right: auto;
                     width:1250px;
                     height:175px;
                     background-color: #ffffff;
                     color: #4a86e8;
                     border: #434343;",
      fluidRow(column(width = 11,
                      actionButton(inputId = paste0("buttonTitle_",USER$list_of_projects[i]),label = USER$list_of_projects[i],style = "background : #4a86e8;background-color: transparent;border-color : transparent; color: #4a86e8; font-size : 30px;")),
                      #tags$h3(paste(USER$list_of_projects[i]))), 
               column(width = 1,
                      tags$button(id = paste0("continueProj_",USER$list_of_projects[i]),class = "btn action-button",img(src = "icons/continue.gif",height = "40px"),style = "background-color: transparent;"))),
      fluidRow(column(width = 1,offset = 11,
                      tags$button(id = paste0("deleteProj_",USER$list_of_projects[i]),class = "btn action-button",img(src = "icons/delete_blue.png",height = "40px"),style = "background-color: transparent;"))),
      fluidRow(column(width = 1,offset = 11,
                      tags$button(id = paste0("shareProj_",USER$list_of_projects[i]),class = "btn action-button",img(src = "icons/share.gif",height = "40px"),style = "background-color: transparent;"))),
      id = i))
   #addPopover(session,paste0("deleteProj_",USER$list_of_projects[i]),"Hello")
  list_ui <<- c(list_ui,i)
  if (is.null(tit_obsList[[paste0("buttonTitle_",USER$list_of_projects[i])]])){
    # make sure to use <<- to update global variable obsList
    tit_obsList[[paste0("buttonTitle_",USER$list_of_projects[i])]] <<- observeEvent(input[[paste0("buttonTitle_",USER$list_of_projects[i])]], {
      continue_project(USER$list_of_projects[i])
    })
  }
  if (is.null(con_obsList[[paste0("continueProj_",USER$list_of_projects[i])]])){
    # make sure to use <<- to update global variable obsList
    con_obsList[[paste0("continueProj_",USER$list_of_projects[i])]] <<- observeEvent(input[[paste0("continueProj_",USER$list_of_projects[i])]], {
      continue_project(USER$list_of_projects[i])
    })
  }
  if (is.null(del_obsList[[paste0("deleteProj_",USER$list_of_projects[i])]])){
    # make sure to use <<- to update global variable obsList
    del_obsList[[paste0("deleteProj_",USER$list_of_projects[i])]] <<- observeEvent(input[[paste0("deleteProj_",USER$list_of_projects[i])]], {
    delete_project(USER$ID,USER$list_of_projects[i])
    removeUI(
      selector = paste0('#', i)
    )
    })
  }
  if (is.null(sha_obsList[[paste0("shareProj_",USER$list_of_projects[i])]])){
    # make sure to use <<- to update global variable obsList
    sha_obsList[[paste0("shareProj_",USER$list_of_projects[i])]] <- observeEvent(input[[paste0("shareProj_",USER$list_of_projects[i])]], {
      showModal(modalDialog(
        title = "You have decided to share your project",
        textInput("receiver_name","Please state the Login of the user you want to share your project with :"),
        hidden(p(id="enter_receiver","Please enter a user to share this project with ",style="font-size:10px;color:red;")),
        hidden(p(id="receiver_does_not_exist","This user does not exist",style="font-size:10px;color:red;")),
        hidden(p(id="receiver_has_access","This user already has access to this project",style="font-size:10px;color:red;")),
        footer = tagList(
          modalButton("Cancel"),
          actionButton("ok_shareProj", "OK")
          
        ),
        easyClose = TRUE
        )
      )
      if(input$receiver_name == ""){
        shinyjs::hide("receiver_does_not_exist")
        shinyjs::show("enter_receiver")
        shinyjs::hide("receiver_has_access")
      }
      else if(USER_in_database(input$receiver_name)==FALSE){
        shinyjs::show("receiver_does_not_exist")
        shinyjs::hide("enter_receiver")
        shinyjs::hide("receiver_has_access")
      }
      else if(has_access(input$receiver_name,USER$list_of_projects[i])){
        shinyjs::hide("receiver_does_not_exist")
        shinyjs::hide("enter_receiver")
        shinyjs::show("receiver_has_access")
      }
      else{
        invite_to_project(USER$ID,input$receiver_name,USER$list_of_projects[i])
        removeModal()
      }
    })
  
  }
}
  output$listproj <- renderText({unlist(USER$list_of_projects)})
  output$lenproj <- renderText({length(USER$list_of_projects)})
  output$uis <- renderText({unlist(tit_obsList)})
}

What is extraneous now is that, if I have no project, I can create them and all is working well : every button is functional. But if I reload the app, all UIs are present, but only the last button is working : if I have 3 projects P1, P2 and P3, only P3 buttons work, or more precisely, if I click to delete P2, nothing happens, but now if I click to continue P3, both events are triggered and P2 is deleted while P3 is continued. Another strange issue is that if I am in this same P1, P2, P3 situation and I delete P3, then P2 and only P2, the latter one, is functional again, while it was not before P3 was deleted. That means only the last one works.

I repeat that this only happens when I reload the app. If the app is not reloaded, all projects are functional, which is surprising because the list from which they are generated is the same and the place from which I call the code above is the same.

Upvotes: 0

Views: 128

Answers (0)

Related Questions