web-dev-qa-db-fra.com

R Shiny: gérer les boutons d'action dans le tableau de données

J'ai une application R Shiny avec un tableau de données. Une colonne contient des boutons d'action avec un ID unique. J'aimerais gérer les clics sur ces boutons, mais malheureusement, mon code de gestion des événements (une simple déclaration d'impression) n'est jamais exécuté. Voir cet exemple autonome (app.R):

library(shiny)
library(DT)

ui <- shinyUI(
    fluidPage(
        title = "DataTable with Buttons",
        fluidRow(
            column(
                width = 8,
                dataTableOutput("employees")
            )
        )
    )
)

server <- shinyServer(function(input, output) {
    df <- data.frame(
        name = c('Dilbert', 'Alice', 'Wally', 'Ashok', 'Dogbert'),
        motivation = c(62, 73, 3, 99, 52),
        stringsAsFactors = FALSE
    )
    fireButtons <- list()
    fireButtonIds <- list()
    for (r in rownames(df)) {
        id <- paste("fire_", r, sep = "")
        fireButtonIds[[r]] <- id
        button <- actionButton(id, label = "Fire")
        fireButtons[[r]] <- as.character(button)
    }
    df$actions <- fireButtons
    dt <- datatable(df, colnames = c("#", "Name", "Motivation", "Actions"))
    output$employees <- renderDataTable(dt)


    for (id in fireButtonIds) {
        # binding doesn't work
        # - is the path wrong?
        # - is it because the button is really a string, not an object?
        observeEvent(input$employees$x$data$actions[[id]], {
            print(paste("click on", i))
        })
    }
})

shinyApp(ui = ui, server = server)

Je vois deux problèmes possibles:

  1. Le chemin que j'utilise (input$employees$x$data$actions[[id]]) est tout simplement faux
  2. Le chemin que j'utilise est correct, mais il ne pointe pas vers quelque chose qui pourrait réellement être géré, c'est-à-dire juste une chaîne HTML et non un objet bouton.

Ou peut-être existe-t-il une bien meilleure approche pour placer des boutons dans un tableau de données ...?

16
Patrick Bucher

Est-ce que cela accomplit ce que vous essayez de faire?

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)' ),
      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

    })

  }
)
30
kostr