32

I want to modify this application:

https://demo.shinyapps.io/029-row-selection/

so that only one row can be selected at a time, and so that I can acquire the item in the first column of the selected row to plot data with. Does anyone know how to do this?

evolvedmicrobe
  • 2,672
  • 2
  • 22
  • 30

4 Answers4

39

UPDATE: you can now access the selected rows using input$tableId_rows_selected in server.R. See here for more details.

To select a unique row, you can change the callback function of your example to this:

callback = "function(table) {
      table.on('click.dt', 'tr', function() {
            table.$('tr.selected').removeClass('selected');
            $(this).toggleClass('selected');            
        Shiny.onInputChange('rows',
                            table.rows('.selected').data()[0][0]);
      });
    }"

When you click on a row,it basically removes any selected rows (they have the .selected class) and selects the row you clicked on.

I also changed the code in the Shiny.onInputChange function so that it returns the number in the first column.

NicE
  • 21,165
  • 3
  • 51
  • 68
  • How would you modify this code to select multiple rows in from a sorted datatable? I tried `.data()[0][0].toArray()` but it doesn't work. – Komal Rathi May 29 '15 at 19:10
26

The R method which renders a DataTable has a parameter which defines the selection mode. For example:

output$table1 <-
  DT::renderDataTable(dataSet,
                      selection = 'single')

Possible values are ('multiple' is the default):

  • none
  • single
  • multiple

For further reference you can see: http://rstudio.github.io/DT/shiny.html

EDIT 04/14/2016

In the setup I use working with single selection mode has issues.

Here is what version I use:

> DT:::DataTablesVersion
[1] "1.10.7"
> packageVersion("DT")
[1] ‘0.1’

The problem I faced is that visually you have a single row selection but when you do:

observeEvent(input$table1_rows_selected, {
  str(input$table1_rows_selected)
})

You will get a list with all rows which were selected but were not explicitly deselected. In other words selecting a new row does not automatically deselect the previous row in the internal Datatables logic. This might be also due to the DT wrapper, not sure.

This is why currently as a workaround we use JS for this:

$(document).on('click', '#table1 table tr', function() {
    var selectedRowIds = $('#table1 .dataTables_scrollBody table.dataTable').DataTable().rows('.selected')[0];

    var selectedId = "";
    if (selectedRowIds.length === 1) {
        selectedId = $(this).children('td:eq(0)').text();
    } else {
      $('#table1 tbody tr').removeClass('selected');
    }
    Shiny.onInputChange("table1_selected_id", selectedId);
});

Once you have this in place you will be able to do:

observeEvent(input$table1_selected_id, {
  str(input$table1_selected_id)
})

This now at least sends correct data to your server.R code. Unfortunately you will still have an issue with the table because internally it keeps track on which rows were selected and if you switch pages it will restore a wrong selection. But at least this is purely a visual defect and your code will have the chance to function properly. So this solution actually needs more work.

Angel Naydenov
  • 1,585
  • 1
  • 13
  • 14
  • That is still an issue in the CRAN release as of today, but it appears to be fixed in the development version: `devtools::install_github('rstudio/DT')` – teadotjay Aug 08 '16 at 17:47
  • 2
    If you know that you dealing with single selection you may be able to use `_row_last_clicked` – PeterVermont May 11 '17 at 19:01
4

You can use this:

output$data_table <- renderDataTable(data(),options = list(pageLength = 9))

Then to get the selected row:

selected <- input$data_table_rows_selected

Then to get cells from that row, you can use (assuming that time is the name of the col you are trying to get in this case):

time_x = data()[selected, "time"]

Selected is the index for the selected rows, so you need to use that index along with the col name.

bird
  • 2,938
  • 1
  • 6
  • 27
0

The below code display a dataframe in DT table format. Users will be able to select single row. The selected row is retrieved and displayed. you can write your plot function in the plot block in the server.

I hope this helps !!

         # Server.R
         shinyServer(function(input, output,session) {




          output$sampletable <- DT::renderDataTable({
          sampletable
          }, server = TRUE,selection = 'single')  

          output$selectedrow <- DT::renderDataTable({

          selectedrowindex <<-     input$sampletable_rows_selected[length(input$sampletable_rows_selected)]
         selectedrowindex <<- as.numeric(selectedrowindex)
         selectedrow <- (sampletable[selectedrowindex,])
         selectedrow



           })

          output$plots <- renderPlot({

          variable <- sampletable[selectedrowindex,1]
          #write your plot function


              })


          })

          #ui.R 
          shinyUI(navbarPage( "Single Row Selection",



                tabPanel("Row selection example",
                         sidebarLayout(sidebarPanel("Parameters"),
                             mainPanel(
                               DT::dataTableOutput("selectedrow"),   
                             DT::dataTableOutput("sampletable")

                           ))

                      )

                      ))

         # global.R 

        library(DT)
        library(shiny)
        selectedrowindex = 0