Modal 仅在 R Datatable 闪亮应用程序中单击按钮时打开一次 [英] Modal opens up only once on button click in R Datatable shiny app
问题描述
我有一个表格,用于保存书签 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屋!