How to insert selectInput throughout the dataTable

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 display is the div tag, via vlr [i] within 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.

    
asked by anonymous 07.03.2018 / 20:33

1 answer

1

Initially I would like to point out that the example you put generates a STATIC dataTable . So even if you were able to replace yours with an HTML entry type, be it a button or a select from list, STILL, you would have to find a way to send that data to Shiny.

CHANGING INPUT with DataTable

I took the example you quoted and moved to stay with a list instead of the radiobutton . Here is an example code that exchanges the input with 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:

Theproblemisthatwiththiscodeyoucanonlytaketheexamplesfromthelistinthefirstcolumn.Ididnotfindaneasywaytogetelementbyelementoftable.AndalsonotethatthistableintheexampleyoumentionedhadthefunctiontoreturnONLYONENUMBERPERLINE.IwouldhavetothinkbetterhowtoaccessthedataTablecellswithinShiny.

ALTERNATIVESOLUTION

IbelievethatfortheproblemyouwanttosolvethereisanotherpackagethatisIDEAL.Thispackageis rhandsontable . Here is an example of a table generated by it:

Thecodethatgeneratedthistablewasthis:

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 it is not the appropriate tool for this type of interaction.

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

    
01.05.2018 / 05:01