title: Shiny: Select single row in DT with checkbox
body: <p>In the example here there is an example of how to select rows with a checkbox: <a href="https://stackoverflow.com/questions/48854547/r-shiny-how-to-make-datatable-react-to-checkboxes-in-datatable">R Shiny, how to make datatable react to checkboxes in datatable</a></p>
  
  <p>That works fine. But I need to only be able to select a single row.</p>
  
  <p><br></p>
  
  <p>I got close but there are two problems:</p>
  
  <ol>
  <li>when a box is ticked the reactive is trigger twice. I don't understand why. But then again I don't understand what activates the reactive since I don't see the input directly inside the reactive...</li>
  <li>If I click on the same box twice the selection is not really updated.</li>
  </ol>
  
  <p><br>
  Any clue appreciated.</p>
  
  <p>What I got so far. I also have a feeling I am over complicating things.</p>
  
  <pre class="lang-r prettyprint-override"><code>library(shiny)
  library(DT)
  shinyApp(
    ui = fluidPage(
      DT::dataTableOutput('x1'),
      verbatimTextOutput('x2')
    ),
  
    server = function(input, output, session) {
      # create a character vector of shiny inputs
      shinyInput = function(FUN, len, id, value, ...) {
        if (length(value) == 1) value &lt;- rep(value, len)
        inputs = character(len)
        for (i in seq_len(len)) {
          inputs[i] = as.character(FUN(paste0(id, i), label = NULL, value = value[i]))
        }
        inputs
      }
  
      # obtain the values of inputs
      shinyValue = function(id, len) {
        unlist(lapply(seq_len(len), function(i) {
          value = input[[paste0(id, i)]]
          if (is.null(value)) FALSE else value
        }))
      }
  
      n = 6
      df = data.frame(
        cb = shinyInput(checkboxInput, n, 'cb_', value = FALSE, width='1px'),
        month = month.abb[1:n],
        YN = rep(FALSE, n),
        ID = seq_len(n),
        stringsAsFactors = FALSE)
  
      df_old &lt;- df
  
  
      loopData = reactive({
  
  
        checked &lt;- shinyValue('cb_', n)
  
        changed &lt;- which((checked-df_old$YN)!=0)
  
        print(checked)
        print(changed)
  
        if(length(changed)==0){ df 
          }else{
  
  
        df$cb &lt;&lt;- shinyInput(checkboxInput, n, 'cb_', value = rep(FALSE, n), width='1px')
        df$YN &lt;&lt;- FALSE
  
        df$YN[changed] &lt;&lt;- checked[changed]
        df$cb[changed] &lt;&lt;- shinyInput(checkboxInput, length(changed), 'cb_', value = df$YN[changed], width='1px')
  
  
        df_old &lt;&lt;- df
        df
          }
  
      })
  
      output$x1 = DT::renderDataTable(
        isolate(loopData()),
        escape = FALSE, selection = 'none',
        options = list(
          dom = 't', paging = FALSE, ordering = FALSE,
          preDrawCallback = JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
          drawCallback = JS('function() { Shiny.bindAll(this.api().table().node()); } ')
        ))
  
      proxy = dataTableProxy('x1')
  
      observe({
        replaceData(proxy, loopData(), resetPaging = FALSE)
      })
  
      output$x2 = renderPrint({
        data.frame(Like = shinyValue('cb_', n))
      })
    }
  )
  </code></pre>
  
  <p><br><br>
  EDIT:
  I adapted @Stéphane Laurent's solution to my use, but there is a slight vertical alignment issue.<br>
  <a href="https://i.stack.imgur.com/1olJZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1olJZ.png" alt="enter image description here"></a></p>