【问题标题】:modalDialog inside a loop in shinyappShinyapp中循环内的modalDialog
【发布时间】:2022-07-31 04:25:04
【问题描述】:

如何在循环中使用modalDialog?我查看了一些论坛,但没有一个令人满意或不适合我的问题。

以下是模拟我的问题的最小可重现代码。 RShiny: How to have sequential Modals in for loop 中提出的解决方案不起作用,因为我在shinyalert 函数的text 参数中输入的actionbutton 无法在observeEvent 中识别。

library(shiny)

dialog_filtro <- function(ID,LabelID,messagee){ 
  modalDialog(
          title = "Menssagem importante",
          messagee,
          footer = tagList(
                           actionButton(ID[1],LabelID[1]),
                           actionButton(ID[2],LabelID[2])
                           )
           )
}

ui <- fluidPage(
           uiOutput('res')
)

server <- function(input, output, session) {
  
      RESFIL <- reactiveValues(dest = NULL)
      lista <- list(a=2,a=3)
      grupdest <- rep(list(NA),length(lista))
      RESFIL$dest <- grupdest
      
      for(i in 1:length(lista)){
          
          if(lista[[i]] > 0){
            
             showModal(dialog_filtro(ID = c(paste0('yes',i),paste0('no',i)),
                     LabelID = c('Yes','No'),
                     messagee = paste0('This is the loop ',i)
                     ))
             
             observeEvent(input[[paste0('yes',i)]], { 
                 RESFIL$dest[[i]] <- i+10
                 removeModal()              
             })
             
             observeEvent(input[[paste0('no',i)]], { 
                 RESFIL$dest[[i]] <- i+100
                 removeModal()             
             })
             
             }else{
                 RESFIL$dest[[i]]  <- i+1000
                 removeModal() 
             }
          }
          
        output$res <- renderPrint({ RESFIL$dest })  
  }

shinyApp(ui = ui, server = server)

【问题讨论】:

  • 循环不是这里的问题:你不能打开两个模态。第二个替换第一个。我去看看能不能找到替代方法。

标签: r for-loop shiny


【解决方案1】:

这是 shinyalert 的一种方式。这很奇怪,如果您在闪亮警报中放置一个按钮,然后单击该按钮会自动关闭警报。这就是我使用actionLink 而不是actionButton 的原因。单击一个按钮/链接时,该应用程序不会像往常一样做出反应,因此我使用运行Shiny.setInputValueonclick 属性。如您所见,我在循环中使用local,否则无法按预期工作。但我认为(我没有测试)你可以使用普通的lapply,而不是使用for+local

library(shiny)
library(shinyalert)

dialog_filtro <- function(i, input, session, RESFIL, ID, LabelID, messagee) {
  al <- shinyalert(
    title = "Menssagem importante",
    text = tagList(
      tags$p(messagee),
      actionLink(
        ID[1], LabelID[1], class = "btn btn-primary",
        onclick = sprintf(
          'Shiny.setInputValue("%s", true, {priority: "event"});', 
          ID[1]
        )
      ),
      actionLink(
        ID[2], LabelID[2], class = "btn btn-primary",
        onclick = sprintf(
          'Shiny.setInputValue("%s", true, {priority: "event"});', 
          ID[2]
        )
      ),
    ),
    html = TRUE,
    session = session
  )
  observeEvent(input[[ID[1]]], {
    RESFIL$dest[[i]] <- i + 10
    closeAlert(id = al)
  }, domain = session)
  observeEvent(input[[ID[2]]], {
    RESFIL$dest[[i]] <- i + 100
    closeAlert(id = al)
  }, domain = session)
}

ui <- fluidPage(
  verbatimTextOutput("res")
)

server <- function(input, output, session) {
  
  RESFIL <- reactiveValues(dest = NULL)
  lista <- list(a = 2, a = 3)
  grupdest <- rep(list(0), length(lista))
  RESFIL$dest <- grupdest
  
  for (i0 in 1:length(lista)) {
    local({
      
      i <- i0
      
      if (lista[[i]] > 0) {
        
        dialog_filtro(
          i,
          input,
          session,
          RESFIL, 
          ID = c(paste0("yes", i), paste0("no", i)),
          LabelID = c("Yes", "No"),
          messagee = paste0("This is the loop ", i)
        )
        
      } else {
        RESFIL$dest[[i]] <- i + 1000
        # removeModal() not clear what you want to do here: remove which modal?
      }
      
    })
  }
  
  output$res <- renderPrint({
    RESFIL$dest
  })
}

shinyApp(ui = ui, server = server)

【讨论】:

  • 太棒了!!!!非常感谢!祝您度过愉快的一周
  • 它可以与lapply 一起使用,而不需要local 函数。谢谢。
猜你喜欢
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2021-09-14
相关资源
最近更新 更多