modalDialog 在单击相同行后不会打开 reactable

huangapple go评论94阅读模式
英文:

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的标题显示汽车名称。

  1. library(shiny)
  2. library(tidyverse)
  3. library(reactable)
  4. ui <- fluidPage(
  5. fluidRow(
  6. column(12, align = 'center', reactableOutput("tbl"))
  7. )
  8. )
  9. server <- function(input, output, session) {
  10. data = reactive({
  11. mtcars %>% add_rownames('car')
  12. })
  13. output$tbl = renderReactable(
  14. reactable(
  15. data(),
  16. defaultPageSize = 10,
  17. compact = T,
  18. highlight = T,
  19. defaultColDef = colDef(headerClass = "bar-sort-header",
  20. sortNALast = T, align = 'center',
  21. headerVAlign = 'center',
  22. vAlign = 'center',
  23. minWidth = 60
  24. ),
  25. onClick = JS("function(rowInfo, colInfo) {
  26. Shiny.setInputValue('foo', rowInfo.id)
  27. }"),
  28. rowStyle = list(cursor = "pointer")
  29. )
  30. )
  31. observeEvent(input$foo, {
  32. print(input$foo)
  33. showModal(
  34. modalDialog(
  35. size = 'l',
  36. easyClose = T,
  37. title = data()$car[as.numeric(input$foo)+1],
  38. )
  39. )
  40. })
  41. }
  42. 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.

  1. library(shiny)
  2. library(tidyverse)
  3. library(reactable)
  4. ui &lt;- fluidPage(
  5. fluidRow(
  6. column(12, align = &#39;center&#39;,reactableOutput(&quot;tbl&quot;))
  7. )
  8. )
  9. server &lt;- function(input, output, session) {
  10. data = reactive({
  11. mtcars %&gt;% add_rownames(&#39;car&#39;)
  12. })
  13. output$tbl = renderReactable(
  14. reactable(
  15. data(),
  16. defaultPageSize = 10,
  17. compact = T,
  18. highlight = T,
  19. defaultColDef = colDef(headerClass = &quot;bar-sort-header&quot;,
  20. sortNALast = T, align = &#39;center&#39;,
  21. headerVAlign = &#39;center&#39;,
  22. vAlign = &#39;center&#39;,
  23. minWidth = 60
  24. ),
  25. onClick = JS(&quot;function(rowInfo, colInfo) {
  26. Shiny.setInputValue(&#39;foo&#39;, rowInfo.id)
  27. }&quot;),
  28. rowStyle = list(cursor = &quot;pointer&quot;)
  29. )
  30. )
  31. observeEvent(input$foo, {
  32. print(input$foo)
  33. showModal(
  34. modalDialog(
  35. size = &#39;l&#39;,
  36. easyClose = T,
  37. title = data()$car[as.numeric(input$foo)+1],
  38. )
  39. )
  40. })
  41. }
  42. shinyApp(ui = ui, server = server)

答案1

得分: 3

以下是代码部分的翻译:

  1. library(shiny)
  2. library(tidyverse)
  3. library(reactable)
  4. ui &lt;- fluidPage(
  5. tags$head(
  6. tags$script(
  7. &quot;Shiny.addCustomMessageHandler(&#39;update_input_foo&#39;, function(value) {
  8. Shiny.setInputValue(&#39;foo&#39;, null)
  9. });
  10. &quot;)
  11. ),
  12. fluidRow(
  13. column(12, align = &#39;center&#39;,reactableOutput(&quot;tbl&quot;))
  14. )
  15. )
  16. server &lt;- function(input, output, session) {
  17. data = reactive({
  18. mtcars %&gt;% add_rownames(&#39;car&#39;)
  19. })
  20. output$tbl = renderReactable(
  21. reactable(
  22. data(),
  23. defaultPageSize = 10,
  24. compact = T,
  25. highlight = T,
  26. defaultColDef = colDef(headerClass = &quot;bar-sort-header&quot;,
  27. sortNALast = T, align = &#39;center&#39;,
  28. headerVAlign = &#39;center&#39;,
  29. vAlign = &#39;center&#39;,
  30. minWidth = 60
  31. ),
  32. onClick = JS(&quot;function(rowInfo, colInfo) {
  33. Shiny.setInputValue(&#39;foo&#39;, rowInfo.id)
  34. }&quot;),
  35. rowStyle = list(cursor = &quot;pointer&quot;)
  36. )
  37. )
  38. r &lt;- reactiveVal(NULL)
  39. observeEvent(input$foo, {
  40. if (!is.null(input$foo)) {
  41. showModal(
  42. modalDialog(
  43. size = &#39;l&#39;,
  44. easyClose = T,
  45. title = data()$car[as.numeric(input$foo)+1],
  46. )
  47. )
  48. session$sendCustomMessage(&quot;update_input_foo&quot;, 1)
  49. }
  50. })
  51. }
  52. 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:

  1. library(shiny)
  2. library(tidyverse)
  3. library(reactable)
  4. ui &lt;- fluidPage(
  5. tags$head(
  6. tags$script(
  7. &quot;Shiny.addCustomMessageHandler(&#39;update_input_foo&#39;, function(value) {
  8. Shiny.setInputValue(&#39;foo&#39;, null)
  9. });
  10. &quot;)
  11. ),
  12. fluidRow(
  13. column(12, align = &#39;center&#39;,reactableOutput(&quot;tbl&quot;))
  14. )
  15. )
  16. server &lt;- function(input, output, session) {
  17. data = reactive({
  18. mtcars %&gt;% add_rownames(&#39;car&#39;)
  19. })
  20. output$tbl = renderReactable(
  21. reactable(
  22. data(),
  23. defaultPageSize = 10,
  24. compact = T,
  25. highlight = T,
  26. defaultColDef = colDef(headerClass = &quot;bar-sort-header&quot;,
  27. sortNALast = T, align = &#39;center&#39;,
  28. headerVAlign = &#39;center&#39;,
  29. vAlign = &#39;center&#39;,
  30. minWidth = 60
  31. ),
  32. onClick = JS(&quot;function(rowInfo, colInfo) {
  33. Shiny.setInputValue(&#39;foo&#39;, rowInfo.id)
  34. }&quot;),
  35. rowStyle = list(cursor = &quot;pointer&quot;)
  36. )
  37. )
  38. r &lt;- reactiveVal(NULL)
  39. observeEvent(input$foo, {
  40. if (!is.null(input$foo)) {
  41. showModal(
  42. modalDialog(
  43. size = &#39;l&#39;,
  44. easyClose = T,
  45. title = data()$car[as.numeric(input$foo)+1],
  46. )
  47. )
  48. session$sendCustomMessage(&quot;update_input_foo&quot;, 1)
  49. }
  50. })
  51. }
  52. shinyApp(ui = ui, server = server)

答案2

得分: 2

以下是您要翻译的代码部分:

  1. library(shiny)
  2. library(tidyverse)
  3. library(reactable)
  4. ui <- fluidPage(
  5. fluidRow(
  6. column(12, align = 'center', reactableOutput("tbl"))
  7. )
  8. )
  9. server <- function(input, output, session) {
  10. data = reactive({
  11. mtcars %>% tibble::rownames_to_column('car')
  12. })
  13. output$tbl = renderReactable(
  14. reactable(
  15. data(),
  16. defaultPageSize = 10,
  17. compact = T,
  18. highlight = T,
  19. defaultColDef = colDef(headerClass = "bar-sort-header",
  20. sortNALast = T, align = 'center',
  21. headerVAlign = 'center',
  22. vAlign = 'center',
  23. minWidth = 60
  24. ),
  25. onClick = JS("function(rowInfo, colInfo) {
  26. Shiny.setInputValue('foo', {id:rowInfo.id, nonce:Math.random()})
  27. }"),
  28. rowStyle = list(cursor = "pointer")
  29. )
  30. )
  31. observeEvent(input$foo, {
  32. print(input$foo)
  33. id <- input$foo$id
  34. row_nr <- as.numeric(id) + 1
  35. showModal(
  36. modalDialog(
  37. size = 'l',
  38. easyClose = T,
  39. title = data()$car[row_nr]
  40. )
  41. )
  42. })
  43. }
  44. 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.

  1. library(shiny)
  2. library(tidyverse)
  3. library(reactable)
  4. ui &lt;- fluidPage(
  5. fluidRow(
  6. column(12, align = &#39;center&#39;,reactableOutput(&quot;tbl&quot;))
  7. )
  8. )
  9. server &lt;- function(input, output, session) {
  10. data = reactive({
  11. mtcars %&gt;% tibble::rownames_to_column(&#39;car&#39;)
  12. })
  13. output$tbl = renderReactable(
  14. reactable(
  15. data(),
  16. defaultPageSize = 10,
  17. compact = T,
  18. highlight = T,
  19. defaultColDef = colDef(headerClass = &quot;bar-sort-header&quot;,
  20. sortNALast = T, align = &#39;center&#39;,
  21. headerVAlign = &#39;center&#39;,
  22. vAlign = &#39;center&#39;,
  23. minWidth = 60
  24. ),
  25. onClick = JS(&quot;function(rowInfo, colInfo) {
  26. Shiny.setInputValue(&#39;foo&#39;, {id:rowInfo.id, nonce:Math.random()})
  27. }&quot;),
  28. rowStyle = list(cursor = &quot;pointer&quot;)
  29. )
  30. )
  31. observeEvent(input$foo, {
  32. print(input$foo)
  33. id &lt;- input$foo$id
  34. row_nr &lt;- as.numeric(id)+1
  35. showModal(
  36. modalDialog(
  37. size = &#39;l&#39;,
  38. easyClose = T,
  39. title = data()$car[row_nr],
  40. )
  41. )
  42. })
  43. }
  44. shinyApp(ui = ui, server = server)

huangapple
  • 本文由 发表于 2023年2月23日 21:31:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545530.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定