Modal 仅在 R Datatable 闪亮应用程序中单击按钮时打开一次 [英] Modal opens up only once on button click in R Datatable shiny app

查看:20
本文介绍了Modal 仅在 R Datatable 闪亮应用程序中单击按钮时打开一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表格,用于保存书签 URL.截至目前,当您单击按钮时,它会打开模态.但是,一旦您拥有第二条记录并单击该按钮,它就不会打开模态.此外,当模态现在打开时,它有一个 href.如何清理它并只显示 URL?

I have a table in which I am saving the bookmark URL. As of now when you click on the button it opens the modal. But as soon as you have the second record and click on that button it doesn't open up the modal. Also when the modal opens as of now it has a href. How can I clean it up and just show the URL?

library(shiny)
library(RSQLite)
library(data.table)
library(DT)
library(dplyr)
library(rclipboard)
library(shinyBS)



ui <- function(request) {
  fluidPage(rclipboardSetup(),
    DT::dataTableOutput("x1"),
    column(
      12,
      column(3,tags$div(title="forecast", numericInput("budget_input", label = ("Total Forecast"), value = 2))),
      column(2, textInput(inputId = "description", label = "Bookmark description", placeholder = "Data Summary")),
      column(2, bookmarkButton(id="bookmarkBtn"))),
    column(2, actionButton("opt_run", "Run")),
    DT::dataTableOutput("urlTable", width = "100%"),
    tags$style(type='text/css', "#bookmarkBtn { width:100%; margin-top: 25px;}")
  )
}

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

  con <- dbConnect(RSQLite::SQLite(), "bookmarks.db", overwrite = FALSE)
  myBookmarks <- reactiveValues(urlDF = NULL)

  observeEvent(input$bookmarkBtn, {
    session$doBookmark()
  })

  observeEvent(input$opt_run, {
    cat('HJE')
  })

  output$x1 <- DT::renderDataTable({
    input$opt_run
    isolate({
      datatable(
        df %>% mutate(Current  = as.numeric(Current)*(input$budget_input)), selection = 'none', editable = TRUE
      )
    })
  })

  if(dbExistsTable(con, "Bookmarks")){
    tmpUrlDF <- data.table(dbReadTable(con, "Bookmarks"))
    myBookmarks$urlDF <- tmpUrlDF[, Timestamp := as.POSIXct(Timestamp, origin="1970-01-01 00:00")]
  } else {
    myBookmarks$urlDF <- NULL
  }

  session$onSessionEnded(function() {
    tmpUrlDF <- isolate({myBookmarks$urlDF})
    if(!is.null(tmpUrlDF)){
      dbWriteTable(con, "Bookmarks", tmpUrlDF, overwrite = TRUE)
    }
    dbDisconnect(con)
  })

  setBookmarkExclude(c("bookmarkBtn", "description", "urlTable_cell_clicked", "urlTable_rows_all", "urlTable_rows_current", "urlTable_rows_selected", "urlTable_search", "urlTable_state", "urlTable_row_last_clicked"))

  df <- data.table(Channel = c("A", "B","C"),
                   Current = c("2000", "3000","4000"),
                   Modified = c("2500", "3500","3000"),
                   New_Membership = c("450", "650","700"))


  shinyInput <- function(FUN, len, id, ...) {
    inputs <- character(len)
    for (i in seq_len(len)) {
      inputs[i] <- as.character(FUN(paste0(id, i), ...))
    }
    inputs
  }

  onBookmarked(fun=function(url){
    if(!url %in% myBookmarks$urlDF$URL){
      if(is.null(myBookmarks$urlDF)){
        myBookmarks$urlDF <-
          unique(
            data.table(
              Description = input$description,
              URL = paste0("<a href='", url, "'>", url, "</a>"),
              Share = shinyInput(actionButton, 10, 'button_', label = "Assessment", onclick = 'Shiny.onInputChange("select_button",  this.id)' ),
              Timestamp = Sys.time(),
              Session = session$token,
              User = Sys.getenv("USERNAME")
            ),
            by = "URL"
          )
      } else {
        myBookmarks$urlDF <-
          unique(rbindlist(list(
            myBookmarks$urlDF,
            data.table(
              Description = input$description,
              URL = paste0("<a href='", url, "'>", url, "</a>"),
              Share = shinyInput(actionButton, 10, 'button_', label = "Assessment", onclick = 'Shiny.onInputChange("select_button",  this.id)' ),
              Timestamp = Sys.time(),
              Session = session$token,
              User = Sys.getenv("USERNAME")
            )
          )), by = "URL")
      }
    }
  })
  observeEvent(input$select_button, {
  showModal(urlModal(
   myBookmarks$urlDF[input$urlTable_rows_selected,URL],
    title = "You have selected a row!"
  ))
  })

  output$urlTable = DT::renderDataTable({
    req(myBookmarks$urlDF)
    myBookmarks$urlDF[User %in% Sys.getenv("USERNAME")] 
  }, escape=FALSE)

}
enableBookmarking(store = "url")
shinyApp(ui, server)

推荐答案

这就是我认为您所追求的:

Here is what I think you are after:

library(shiny)
library(RSQLite)
library(data.table)
library(DT)
library(dplyr)
library(shinyjs)

ui <- function(request) {
  fluidPage(
    useShinyjs(),
    DT::dataTableOutput("x1"),
    column(
      12,
      column(3, tags$div(title="forecast", numericInput("budget_input", label = ("Total Forecast"), value = 2))),
      column(2, textInput(inputId = "description", label = "Bookmark description", placeholder = "Data Summary")),
      column(2, bookmarkButton(id="bookmarkBtn"))),
    column(2, actionButton("opt_run", "Run")),
    DT::dataTableOutput("urlTable", width = "100%"),
    tags$style(type='text/css', "#bookmarkBtn { width:100%; margin-top: 25px;}")
  )
}

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

  con <- dbConnect(RSQLite::SQLite(), "bookmarks.db", overwrite = FALSE)
  myBookmarks <- reactiveValues(urlDF = NULL)

  observeEvent(input$bookmarkBtn, {
    session$doBookmark()
  })

  observeEvent(input$opt_run, {
    cat('HJE')
  })

  df <- data.table(Channel = c("A", "B","C"),
                   Current = c("2000", "3000","4000"),
                   Modified = c("2500", "3500","3000"),
                   New_Membership = c("450", "650","700"))

  output$x1 <- DT::renderDataTable({
    input$opt_run
    req(input$budget_input)
    isolate({
      datatable(
        df %>% mutate(Current  = as.numeric(Current)*(input$budget_input)), selection = 'none', editable = TRUE
      )
    })
  }, server = FALSE)

  if(dbExistsTable(con, "Bookmarks")){
    tmpUrlDF <- data.table(dbReadTable(con, "Bookmarks"))
    myBookmarks$urlDF <- tmpUrlDF[, Timestamp := as.POSIXct(Timestamp, origin="1970-01-01 00:00")]
  } else {
    myBookmarks$urlDF <- NULL
  }

  observe({
    toExclude <- c("bookmarkBtn", "description", "urlTable_cell_clicked", "urlTable_rows_all", "urlTable_rows_current", "urlTable_rows_selected", "urlTable_search", "urlTable_state", "urlTable_row_last_clicked")

    if(!is.null(myBookmarks$urlDF)){
      shareBtnExclude <- paste0("shareBtn", seq_len(nrow(myBookmarks$urlDF)))
      toExclude <- c(toExclude, shareBtnExclude)
    }

    delayExclude <- grep("delay", names(input), value = TRUE)
    if(length(delayExclude) > 0){
      toExclude <- c(toExclude, delayExclude)
    }

    setBookmarkExclude(toExclude)
  })

  session$onSessionEnded(function() {
    tmpUrlDF <- isolate({myBookmarks$urlDF})
    if(!is.null(tmpUrlDF)){
      dbWriteTable(con, "Bookmarks", tmpUrlDF, overwrite = TRUE)
    }
    dbDisconnect(con)
  })

  onBookmarked(fun=function(url){
    if(!url %in% myBookmarks$urlDF$Link){
      if(is.null(myBookmarks$urlDF)){
        myBookmarks$urlDF <-
          unique(
            data.table(
              Description = input$description,
              Link = paste0("<a href='", url, "'>", url, "</a>"),
              Share = as.character(actionButton(inputId=paste0("shareBtn", 1), label = "Assessment", onclick = sprintf('Shiny.setInputValue("shareBtn1", "%s", {priority: "event"});', url))),
              Timestamp = Sys.time(),
              Session = session$token,
              User = Sys.getenv("USERNAME")
            ),
            by = "Link"
          )
      } else {
        myBookmarks$urlDF <-
          unique(rbindlist(list(
            myBookmarks$urlDF,
            data.table(
              Description = input$description,
              Link = paste0("<a href='", url, "'>", url, "</a>"),
              Share = as.character(actionButton(inputId=paste0("shareBtn", nrow(myBookmarks$urlDF)+1), label = "Assessment", onclick = sprintf('Shiny.setInputValue("%s", "%s", {priority: "event"});', paste0("shareBtn", nrow(myBookmarks$urlDF)+1), url))),
              Timestamp = Sys.time(),
              Session = session$token,
              User = Sys.getenv("USERNAME")
            )
          )), by = "Link")
      }
    }
  })

  output$urlTable = DT::renderDataTable({
    req(myBookmarks$urlDF)
    myBookmarks$urlDF[User %in% Sys.getenv("USERNAME")] 
  }, escape=FALSE, selection = 'none')

  observeEvent(lapply(paste0("shareBtn", seq_len(nrow(req(myBookmarks$urlDF)))), function(x) input[[x]]), {
    req(myBookmarks$urlDF)
    delay(100, {req(input[[paste0("shareBtn", input$urlTable_cell_clicked$row)]])
      showModal(urlModal(
        input[[paste0("shareBtn", input$urlTable_cell_clicked$row)]],
        title = paste("You have selected row", input$urlTable_cell_clicked$row)
      ))}
    )
  }, ignoreInit = TRUE)

}

enableBookmarking(store = "url")
shinyApp(ui, server)

我挂断了您对 shinyInput 的调用,您要求该函数每行创建 10 个操作按钮.我还更改了 onclick 参数以直接传递 url.

I dropped your call to shinyInput, you asked the function to create 10 action buttons per row. Also I changed the onclick argument to directly pass the url.

老实说,我不认为将这些按钮添加到每个数据表行是一个好的选择,因为您必须通过 setBookmarkExclude 跟踪要从书签中排除的动态生成的输入(这似乎不太好用).

To be honest I don't think adding those buttons to every datatable row is a good choice, because you have to keep track of the dynamically generated inputs which you want to exclude from bookmarking via setBookmarkExclude (This doesn't seem to work very well).

将排除部分放在单独的 observer 而不是onBookmark 函数似乎可以解决这个问题.

putting the exclude part in a separate observer instead of the onBookmark function seems to fix the situation.

尽管如此,this 对于创建由动态创建的按钮触发的观察者非常有帮助.

Nevertheless, this was very helpful to create an observer which is triggered by the dynamically created buttons.

点击链接后直接将 url 复制到剪贴板的解决方案会更优雅,但应该在另一个问题中解决.

A solution which directly copies the url to the clipboard after clicking the link would be more elegant, but should be adressed in another question.

这篇关于Modal 仅在 R Datatable 闪亮应用程序中单击按钮时打开一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆