DataTables DT: reset value of clicked cell

我怕爱的太早我们不能终老 提交于 2020-01-07 02:57:13

问题


I wanted to add the functionality of something happening after a table cell was clicked (e.g. open a modal). Because (suppose my dt is has the ID "dt") input$dt_cell_clicked stays the same until I click a new cell, I cannot execute the same event on re-clicking that cell.

I tried working around it resetting input$dt_cell_clicked with javascript manually. This works, but there seems to be an internal updatemarker in DT that noticed I clicked the cell before and does not set the value of input$dt_cell_clicked to the clicked value. Is there a workaround or is this a bug?

Thanks!

Minimal example:

library(shiny)
library(shinyjs)

ui <- fluidPage(
  h2("Last clicked:"),
  verbatimTextOutput("last_clicked"),
  actionButton("reset", "Reset clicked value"),
  h2("Datatable:"),
  DT::dataTableOutput("dt"),
  useShinyjs(),
  extendShinyjs(text = paste0("shinyjs.resetDTClick = function() { Shiny.onInputChange('dt_cell_clicked', null); }"))
)

server <- function(input, output) {

  # the last clicke value
  output$last_clicked <- renderPrint({
    str(input$dt_cell_clicked)
  })

  output$dt <- DT::renderDataTable({
    DT::datatable(head(mtcars, 2))
  })

  observeEvent(input$dt_cell_clicked, {
    validate(need(length(input$dt_cell_clicked) > 0, ''))
    alert("You clicked something!")
  })

  observeEvent(input$reset, {
    js$resetDTClick()
  })
}

shinyApp(ui, server)

回答1:


After the hint of using a proxy (Gregor de Cillia), I found a workaround using a detour: the last selected cell. This last selected cell is observed and some action is executed upon a new selection. We can reset the selection by using a DT proxy.

library(shiny)

ui <- fluidPage(
  h2("Last clicked:"),
  verbatimTextOutput("last_clicked"),
  actionButton("reset", "Reset clicked value"),
  h2("Datatable:"),
  DT::dataTableOutput("dt")
)

server <- function(input, output) {

  # the last clicked=selected value
  output$last_clicked <- renderPrint({
    str(input$dt_rows_selected)
  })

  output$dt <- DT::renderDataTable({
    DT::datatable(head(mtcars, 2), selection = 'single')
  })

  # do some action after selecting a value
  observeEvent(input$dt_rows_selected, {
    validate(need(!is.null(input$dt_rows_selected), ''))
    print("You clicked something!")
  })

  myProxy = DT::dataTableProxy('dt')

  # reset last selected value using the proxy
  observeEvent(input$reset, {
    DT::selectRows(myProxy, NULL)
  })
}

shinyApp(ui, server)



回答2:


Here is a version that does resets correctly. It uses a reactive value (called last) that gets set to NULL whenever the reset button is pressed and takes the value of input$dt_cell_clicked whenever this value is updated.

I also removed the dependency from shinyjs by using a dataTableProxy together with selectRows

library(shiny)

ui <- fluidPage(
  h2("Last clicked:"),
  verbatimTextOutput("last_clicked"),
  actionButton("reset", "Reset clicked value"),
  h2("Datatable:"),
  DT::dataTableOutput("dt")
)

server <- function(input, output) {

  # the last clicke value
  output$last_clicked <- renderPrint({
    str(last())
  })

  output$dt <- DT::renderDataTable({
    DT::datatable(head(mtcars, 2))
  })

  observeEvent(input$dt_cell_clicked, {
    validate(need(length(input$dt_cell_clicked) > 0, ''))
    print("You clicked something!")
  })

  myProxy = DT::dataTableProxy('dt')
  last = reactiveVal(NULL)

  observe({
    last(input$dt_cell_clicked)
  })

  observeEvent(input$reset, {
    DT::selectRows(myProxy, NULL)
    last(NULL)
    output$dt <- DT::renderDataTable({    # EDIT
      DT::datatable(head(mtcars, 2))      # EDIT
    })                                    # EDIT
  })
}

shinyApp(ui, server)


来源:https://stackoverflow.com/questions/45065715/datatables-dt-reset-value-of-clicked-cell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!