Search code examples
rshinydt

Add a textbox for each row in rshiny data table displayed in dashboard


Trying to add textbox in each row of a data table displayed shiny dashboard similar to buttons as example below. Each line will have unique value tied similar to what is obtained from the button. I am not able to track the text inputed similar to button. The example code below is taken from Handle actionButtons in DataTable.

library(shiny)
library(DT)

shinyApp(
    ui <- fluidPage(
        DT::dataTableOutput("data"),
        textOutput('myText')
    ),
    
    server <- function(input, output) {
        myValue <- reactiveValues(employee = '')
        
        shinyInput <- function(FUN, len, id, ...) {
            inputs <- character(len)
            for (i in seq_len(len)) {
                inputs[i] <- as.character(FUN(paste0(id, i), ...))
            }
            inputs
        }
        
        df <- reactiveValues(data = data.frame(
            Name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
            Motivation = c(62, 73, 3, 99, 52),
            Actions = shinyInput(actionButton, 5, 'button_', label = "Fire", onclick = 'Shiny.onInputChange(\"select_button\",  this.id)' ),
            TextInput = shinyInput(textInput, 5, 'text_', label = "Write" ),
            stringsAsFactors = FALSE,
            row.names = 1:5
        ))
        
        
        output$data <- DT::renderDataTable(
            df$data, server = FALSE, escape = FALSE, selection = 'none'
        )
        
        observeEvent(input$select_button, {
            selectedRow <- as.numeric(strsplit(input$select_button, "_")[[1]][2])
            myValue$employee <<- paste('click on ',df$data[selectedRow,1])
        })
        
        output$myText <- renderText({
            myValue$employee
        })
    }
)

Solution

  • You could use reactable and reactable.extra see reactable.extra documentation for custom input

    Created an example code snippet using your example here;

    library(shiny)
    library(reactable)
    library(reactable.extras)
    
    shinyApp(
      ui = fluidPage(
        reactable.extras::reactable_extras_dependency(),
        reactableOutput("react"),
        hr(),
        textOutput("button_text"),
        textOutput("text")
      ),
      server = function(input, output) {
        output$react <- renderReactable({
          # preparing the test data
          df <- data.frame(
            Name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
            Motivation = c(62, 73, 3, 99, 52),
            Actions = c('Fire'),
            stringsAsFactors = FALSE,
            Text = c(""),
            row.names = 1:5
          )
          reactable(
            df,
            columns = list(
              Actions = colDef(
                cell = button_extra("button", class = "button-extra")
              ),
              Text = colDef(
                cell = text_extra(
                  "text"
                )
              )
            )
          )
        })
        output$button_text <- renderText({
          req(input$button)
          values <- input$button
          paste0(
            "Button: ",
              paste0("{", paste0(names(values), " : ", unlist(values), 
              collapse = ", "), "}")
          )
        })
    
        output$text <- renderText({
          req(input$text)
          values <- input$text
          paste0(
            "Dropdown: ",
              paste0("{", paste0(names(values), " : ", unlist(values), 
              collapse = ", "), "}")
          )
        })
      }
    )