How to Insert selectInput across the datatable

Asked

Viewed 158 times

2

I’m using the Shiny.
How can I display a selectInput, with options from 1 to 5, in all cells of a DT::datatable?

All I’m getting is the tag div, through the vlr[i] within the for.

library(shiny)  
library(DT)  

ui <- fluidPage(  
   DT::dataTableOutput("tbl")  
)  

server <- function(input, output, session) {  

output$tbl <- DT::renderDataTable(  
    options = list(pageLength = 25), {
    n_rows <- c(1:15)
    n_cols <- c(1:10)

    vlr <- c()  
    n_elem <- (length(n_rows)*length(n_cols))  
    for(i in 1:n_elem){  
       #vlr_of_cc[i] = paste("vlr",i,sep = "_")  
        vlr[i] <- selectInput(paste("vlr",i,sep = "_"), label = NULL, c(0:5), selected = "0")  
    }  

    df <- as.data.frame(matrix(vlr, nrow = 15, ncol = 10, byrow = T, dimnames = list(n_rows, n_cols)))  
})  
}  

shinyApp(ui, server)  

thank you.

  • Hello Fernando, can you give more details about what you are trying to do? Your question is not clear. Thank you

  • It would be like on the link ( rstudio.github.io/DT/011-radio.html ), but with select instead of radio. thank you very much

1 answer

1

Initially I would like to point out that the example you put forth generates a datatable STATIC. So, even if you were able to replace yours with a type of HTML entry, whether it’s a button or a list select, STILL, you’d have to find a way to send this data to Shiny.

EXCHANGING INPUT WITH Datatable

I took the example that you quoted and I switched to a list instead of radiobutton. Here is an example of code that swaps the input for a list:

library(shiny)  
library(DT)  

shinyApp(
  ui = fluidPage(
    title = 'Radio buttons in a table',
    DT::dataTableOutput('foo'),
    verbatimTextOutput('sel')
  ),
  server = function(input, output, session) {
    m = matrix(
      as.character(1:5), nrow = 12, ncol = 5, byrow = TRUE,
      dimnames = list(month.abb, LETTERS[1:5])
    )
    for (i in seq_len(nrow(m))) {
      m[i, ] = sprintf(
        '<select name="%s">
          <option value="volvo">Volvo</option>
          <option value="saab">Saab</option>
          <option value="fiat">Fiat</option>
          <option value="audi">Audi</option>
          </select>',
        month.abb[i], m[i, ]
      )
    }
    m
    output$foo = DT::renderDataTable(
      m, escape = FALSE, selection = 'none', server = FALSE,
      options = list(dom = 't', paging = FALSE, ordering = FALSE),
      callback = JS("table.cells().every(function(i, tab, cell) {
          var $this = $(this.node());
          $this.attr('id', this.data());
          $this.addClass('shiny-input-container');
        });
        Shiny.unbindAll(table.table().node());
        Shiny.bindAll(table.table().node());")
    )
    output$sel = renderPrint({
      sapply(month.abb, function(i) input[[i]])
    })
  }
)

This will generate an app like this:

inserir a descrição da imagem aqui

the problem is that with this code it is only possible to take the examples of the list in the first column. I didn’t find an easy way to get element by element from table. And also note that this table in the example you mentioned had a function to return ONLY ONE NUMBER PER LINE. I would have to think better how to access the datatable cells within Shiny.

WORKAROUND

I believe that for the problem you want to solve there is another package that is IDEAL. This package is the rhandsontable. See an example of a table generated by it:

inserir a descrição da imagem aqui

The code that generated this table was this:

DF = data.frame(integer = 1:10,
                numeric = rnorm(10),
                logical = rep(TRUE, 10), 
                character = LETTERS[1:10],
                factor = factor(letters[1:10], levels = letters[10:1], 
                                ordered = TRUE),
                factor_allow = factor(letters[1:10], levels = letters[10:1], 
                                      ordered = TRUE),
                date = seq(from = Sys.Date(), by = "days", length.out = 10),
                stringsAsFactors = FALSE)

rhandsontable(DF, width = 600, height = 300) %>%
  hot_col("factor_allow", allowInvalid = TRUE)

The great advantage is that this package was made to generate a table for data collection and user interaction. Datatable is great for displaying data and allowing filtering, but is not the appropriate tool for this type of interaction.

Finally, I would like to point out that this table is only the frontend, you will still need a method to export this data to the Shiny server. See the documentation package to know how to do this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.