0
votes

I want to display a table in Shiny with renderDataTable() function. For each row I want to create 2 checkboxes. I'm using checkboxInput() function to create those checkboxes. The checkboxes are created, but when I'm trying to read them with input$checkbox_id, I get NULL.

The same trick works using renderTable(), but my client wants the extra features of DT table (sorting, filtering).

If I inspect the HTML generated, I see that renderTable() inserts and extra class="shiny-bound-input" into the tag. renderDataTable() does not.

library(shiny)
shinyApp(
    ui = fluidPage(
       fluidRow(
         column(12,dataTableOutput('dataTableOutput')),
         column(12,tableOutput('tableOutput')),
         actionButton('printCheckStatus','printCheckStatus')
       )
     ),
     server = function(input, output) {
       df1 <- data.frame(CheckBoxColumn=as.character(checkboxInput("id_1",NULL)))
       df2 <- data.frame(CheckBoxColumn=as.character(checkboxInput("id_2",NULL)))
       output$dataTableOutput <- renderDataTable(df1,escape = FALSE)
       output$tableOutput <- renderTable(df2, sanitize.text.function = function(x) x)

       observeEvent(input$printCheckStatus, {print(input$id_1);print(input$id_2)})
     }
)

The code generates a button and two tables each containing one checkbox. When I click the button I get NULL and FALSE in the console. FALSE is correct, because the second checkbox is unchecked. I get NULL because input$id_1 does not exist in the Shiny server session. I expect FALSE and FALSE in the console log.

1

1 Answers

1
votes

You can use the DT package (based on this):

library(shiny)
library(DT)
shinyApp(
    ui = fluidPage(
        fluidRow(
            column(12,dataTableOutput('dataTableOutput')),
            column(12,tableOutput('tableOutput')),
            actionButton('printCheckStatus','printCheckStatus')
        )
    ),
    server = function(input, output) {
        df1 <- data.frame(CheckBoxColumn=as.character(checkboxInput("id_1",NULL)))
        df2 <- data.frame(CheckBoxColumn=as.character(checkboxInput("id_2",NULL)))
        output$dataTableOutput <- renderDataTable(df1,escape = FALSE, server = FALSE, 
        callback = JS("table.cells().every(function(i, tab, cell) {
          var $this = $(this.node());
          $this.attr('id', this.data()[0]);
          $this.addClass('shiny-input-checkbox');
        });
        Shiny.unbindAll(table.table().node());
        Shiny.bindAll(table.table().node());"))
        output$tableOutput <- renderTable(df2, sanitize.text.function = function(x) x)

        observeEvent(input$printCheckStatus, {print(input$id_1);print(input$id_2)})
    }
)