R shiny observe for row deselection dataTable
Asked Answered
O

3

8

I have a shiny app that has a DT::renderDataTable, the user can select a row in the datatable.

The following bit of code will only print FALSE (when a row is selected):

observeEvent(input$segment_library_datatable_rows_selected, {
  print(is.null(input$segment_library_datatable_rows_selected))
})

How do I get it to print when a row is also deselected? (The print value would be TRUE)

Overriding answered 13/3, 2017 at 3:26 Comment(3)
I guess observeEvent does not trigger when input$segment_library_datatable_rows_selected is NULL. Have you tried a standard observe or reactive function (e.g. sel <- reactive({is.null(input$segment_library_datatable_rows_selected)})). Also please specify if your DT has selection of multiple rows enabled and if you want to detect any changes in the row selection (e.g. also going from 3 to 2 selected rows).Clientage
@KristofferWintherBalling DT selection is set to single, and the above works perfectly.Overriding
have you tried simply: print(!is.null(input$segment_library_datatable_rows_selected))Holub
C
3

As I understand a working minimal example would be the following (sel() reactive is TRUE if a row in datatable is selected):

library(shiny)
library(DT)
ui <- fluidPage(
  DT::dataTableOutput("datatable"),
  textOutput("any_rows_selected")
)
server <- function(input, output) {
  # Output iris dataset
  output$datatable <- DT::renderDataTable(iris, selection = "single")
  # Reactive function to determine if a row is selected
  sel <- reactive({!is.null(input$datatable_rows_selected)})  
  # Output result of reactive function sel
  output$any_rows_selected <- renderText({
    paste("Any rows selected: ", sel())
  })
}
shinyApp(ui, server)
Clientage answered 13/3, 2017 at 8:31 Comment(0)
P
15
observeEvent(input$selected,ignoreNULL = FALSE,{...})

ignoreNULL is defaulted to TRUE. Set to FALSE to have the event observed upon deselection.

Pinhead answered 14/11, 2019 at 16:22 Comment(5)
Not sure why your answer was downvoted - this helped out immensely as I was adding and removing traces from a plotly plot based on rows selected from a DataTable table. Without the ignoreNULL = FALSE my code would remove all traces up until the last row which would fail to remove the trace because the _row_selected would not triggerEsperanzaespial
This is the best! I had a function that would run on the selection of a row with inputs from the selected row, but the result was visible even after the row was de-selected. Tried so many things before I found this reply, and this worked with such little effort.Carline
This is by far the best answer to the question in my opinion. Doesn't require restructuring the entire evnt.Annoy
++top answer hereVariegate
This did the trick, thanks!Fabio
C
3

As I understand a working minimal example would be the following (sel() reactive is TRUE if a row in datatable is selected):

library(shiny)
library(DT)
ui <- fluidPage(
  DT::dataTableOutput("datatable"),
  textOutput("any_rows_selected")
)
server <- function(input, output) {
  # Output iris dataset
  output$datatable <- DT::renderDataTable(iris, selection = "single")
  # Reactive function to determine if a row is selected
  sel <- reactive({!is.null(input$datatable_rows_selected)})  
  # Output result of reactive function sel
  output$any_rows_selected <- renderText({
    paste("Any rows selected: ", sel())
  })
}
shinyApp(ui, server)
Clientage answered 13/3, 2017 at 8:31 Comment(0)
P
3

Alternatively you can use observe() which will respond to any hits to the input$datatable_rows_selected, including NULL.

To repurpose Kristoffer W. B.'s code:

library(shiny)
library(DT)
ui <- fluidPage(
  DT::dataTableOutput("testtable")
)

server <- function(input, output) {
  # Output iris dataset
  output$testtable<- DT::renderDataTable(iris, selection = "single")


  # Observe function that will run on NULL values
  an_observe_func = observe(suspended=T, {
                    input$testtable_rows_selected
                    isolate({
                      #do stuff here
                      print(input$testtable_rows_selected)
                      })
                    })

  #start the observer, without "suspended=T" the observer 
  #  will start on init instead of when needed
  an_observe_func$resume()

shinyApp(ui, server)

A few things to note:

1) I found it best to start the observer in suspended mode, that way it doesn't start when the program initializes. You can turn it on whenever you want it to... observe... (such as after you render the datatable, or before you'd like to start tracking selections).

2) Use isolate to stop the observer from tracking multiple elements. in this case the observer should only react to input$testtable_rows_selected, instead of everything else occurring. The symptom of this problem is that your observer fires multiple times on a single change.

Pasteurize answered 28/9, 2018 at 6:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.