英文:
modalDialog not opening after clicking on the same row in reactable
问题
我目前正在构建一个Shiny应用程序,用户可以在reactable中点击一行,并显示一个modalDialog,其中包含基于该行的更多信息。我遵循了这篇帖子(https://stackoverflow.com/questions/69593193/how-to-trigger-a-modalbox-with-observeevent-from-a-cell-rendered-button-in-a-rea)中的方法来获取onclick
JavaScript函数。
然而,当我使用这个逻辑点击同一行时,没有任何反应。我必须在再次点击相同的行之前先点击另一行。我相信这是因为如果点击的是同一行,input$foo
的值不会改变。
我尝试过在打开modalDialog
时将input$foo
设置为不同的值,但这也没有起作用。有谁知道如何解决这个问题或在打开后重置input$foo
的值?我在JavaScript方面经验有限。下面是一个基本的Shiny示例,在单击特定行后,modalDialog
的标题显示汽车名称。
library(shiny)
library(tidyverse)
library(reactable)
ui <- fluidPage(
fluidRow(
column(12, align = 'center', reactableOutput("tbl"))
)
)
server <- function(input, output, session) {
data = reactive({
mtcars %>% add_rownames('car')
})
output$tbl = renderReactable(
reactable(
data(),
defaultPageSize = 10,
compact = T,
highlight = T,
defaultColDef = colDef(headerClass = "bar-sort-header",
sortNALast = T, align = 'center',
headerVAlign = 'center',
vAlign = 'center',
minWidth = 60
),
onClick = JS("function(rowInfo, colInfo) {
Shiny.setInputValue('foo', rowInfo.id)
}"),
rowStyle = list(cursor = "pointer")
)
)
observeEvent(input$foo, {
print(input$foo)
showModal(
modalDialog(
size = 'l',
easyClose = T,
title = data()$car[as.numeric(input$foo)+1],
)
)
})
}
shinyApp(ui = ui, server = server)
英文:
I am currently building a Shiny app where I'd allow a user to click on a row in a reactable and show a modalDialog with more info based on that row. I followed this post (https://stackoverflow.com/questions/69593193/how-to-trigger-a-modalbox-with-observeevent-from-a-cell-rendered-button-in-a-rea) to get the onclick
JavaScript function.
However, when I click on the same row using this logic, nothing happens. I have to click on another row before I click back to that same row. I believe it's because input$foo
does not change its value if the same row is being clicked.
I've tried setting input$foo
to a different value when the modalDialog
opens, but that has not been working either. Does anyone know how to work around this or reset that input$foo
value after opening? I don't have a ton of experience in JavaScript. A basic Shiny example is shown below where the title of modalDialog
displays the car name after clicking on the specific row.
library(shiny)
library(tidyverse)
library(reactable)
ui <- fluidPage(
fluidRow(
column(12, align = 'center',reactableOutput("tbl"))
)
)
server <- function(input, output, session) {
data = reactive({
mtcars %>% add_rownames('car')
})
output$tbl = renderReactable(
reactable(
data(),
defaultPageSize = 10,
compact = T,
highlight = T,
defaultColDef = colDef(headerClass = "bar-sort-header",
sortNALast = T, align = 'center',
headerVAlign = 'center',
vAlign = 'center',
minWidth = 60
),
onClick = JS("function(rowInfo, colInfo) {
Shiny.setInputValue('foo', rowInfo.id)
}"),
rowStyle = list(cursor = "pointer")
)
)
observeEvent(input$foo, {
print(input$foo)
showModal(
modalDialog(
size = 'l',
easyClose = T,
title = data()$car[as.numeric(input$foo)+1],
)
)
})
}
shinyApp(ui = ui, server = server)
答案1
得分: 3
以下是代码部分的翻译:
library(shiny)
library(tidyverse)
library(reactable)
ui <- fluidPage(
tags$head(
tags$script(
"Shiny.addCustomMessageHandler('update_input_foo', function(value) {
Shiny.setInputValue('foo', null)
});
")
),
fluidRow(
column(12, align = 'center',reactableOutput("tbl"))
)
)
server <- function(input, output, session) {
data = reactive({
mtcars %>% add_rownames('car')
})
output$tbl = renderReactable(
reactable(
data(),
defaultPageSize = 10,
compact = T,
highlight = T,
defaultColDef = colDef(headerClass = "bar-sort-header",
sortNALast = T, align = 'center',
headerVAlign = 'center',
vAlign = 'center',
minWidth = 60
),
onClick = JS("function(rowInfo, colInfo) {
Shiny.setInputValue('foo', rowInfo.id)
}"),
rowStyle = list(cursor = "pointer")
)
)
r <- reactiveVal(NULL)
observeEvent(input$foo, {
if (!is.null(input$foo)) {
showModal(
modalDialog(
size = 'l',
easyClose = T,
title = data()$car[as.numeric(input$foo)+1],
)
)
session$sendCustomMessage("update_input_foo", 1)
}
})
}
shinyApp(ui = ui, server = server)
英文:
I also run into this problem a lot and my approach is to set the input$foo
to null
after calling showModal
so we can click again on the same row:
library(shiny)
library(tidyverse)
library(reactable)
ui <- fluidPage(
tags$head(
tags$script(
"Shiny.addCustomMessageHandler('update_input_foo', function(value) {
Shiny.setInputValue('foo', null)
});
")
),
fluidRow(
column(12, align = 'center',reactableOutput("tbl"))
)
)
server <- function(input, output, session) {
data = reactive({
mtcars %>% add_rownames('car')
})
output$tbl = renderReactable(
reactable(
data(),
defaultPageSize = 10,
compact = T,
highlight = T,
defaultColDef = colDef(headerClass = "bar-sort-header",
sortNALast = T, align = 'center',
headerVAlign = 'center',
vAlign = 'center',
minWidth = 60
),
onClick = JS("function(rowInfo, colInfo) {
Shiny.setInputValue('foo', rowInfo.id)
}"),
rowStyle = list(cursor = "pointer")
)
)
r <- reactiveVal(NULL)
observeEvent(input$foo, {
if (!is.null(input$foo)) {
showModal(
modalDialog(
size = 'l',
easyClose = T,
title = data()$car[as.numeric(input$foo)+1],
)
)
session$sendCustomMessage("update_input_foo", 1)
}
})
}
shinyApp(ui = ui, server = server)
答案2
得分: 2
以下是您要翻译的代码部分:
library(shiny)
library(tidyverse)
library(reactable)
ui <- fluidPage(
fluidRow(
column(12, align = 'center', reactableOutput("tbl"))
)
)
server <- function(input, output, session) {
data = reactive({
mtcars %>% tibble::rownames_to_column('car')
})
output$tbl = renderReactable(
reactable(
data(),
defaultPageSize = 10,
compact = T,
highlight = T,
defaultColDef = colDef(headerClass = "bar-sort-header",
sortNALast = T, align = 'center',
headerVAlign = 'center',
vAlign = 'center',
minWidth = 60
),
onClick = JS("function(rowInfo, colInfo) {
Shiny.setInputValue('foo', {id:rowInfo.id, nonce:Math.random()})
}"),
rowStyle = list(cursor = "pointer")
)
)
observeEvent(input$foo, {
print(input$foo)
id <- input$foo$id
row_nr <- as.numeric(id) + 1
showModal(
modalDialog(
size = 'l',
easyClose = T,
title = data()$car[row_nr]
)
)
})
}
shinyApp(ui = ui, server = server)
英文:
I run into this problem a lot as well, here is a simpler approach with a random value sent each time when the row is clicked.
library(shiny)
library(tidyverse)
library(reactable)
ui <- fluidPage(
fluidRow(
column(12, align = 'center',reactableOutput("tbl"))
)
)
server <- function(input, output, session) {
data = reactive({
mtcars %>% tibble::rownames_to_column('car')
})
output$tbl = renderReactable(
reactable(
data(),
defaultPageSize = 10,
compact = T,
highlight = T,
defaultColDef = colDef(headerClass = "bar-sort-header",
sortNALast = T, align = 'center',
headerVAlign = 'center',
vAlign = 'center',
minWidth = 60
),
onClick = JS("function(rowInfo, colInfo) {
Shiny.setInputValue('foo', {id:rowInfo.id, nonce:Math.random()})
}"),
rowStyle = list(cursor = "pointer")
)
)
observeEvent(input$foo, {
print(input$foo)
id <- input$foo$id
row_nr <- as.numeric(id)+1
showModal(
modalDialog(
size = 'l',
easyClose = T,
title = data()$car[row_nr],
)
)
})
}
shinyApp(ui = ui, server = server)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论