简体   繁体   English

如何根据用户单击将值输入到 Shiny DataTable 中?

[英]How do I input a value into a Shiny DataTable based on a user click?

My example is based on code from Stéphane Laurent with my code below: Change row CSS properties on clicking an icon我的示例基于 Stéphane Laurent 的代码,我的代码如下: 单击图标时更改行 CSS 属性

My goal in addition to changing the CSS properties is to add today's date to the corresponding row where the click was made.除了更改 CSS 属性之外,我的目标是将今天的日期添加到进行点击的相应行。

So far I've created an extra column called the_date , created a reactiveValues dataframe, and then updated it based on an observeEvent.到目前为止,我已经创建了一个名为the_date的额外列,创建了一个reactValues数据,然后根据observeEvent 更新了它。 When the "x" is clicked the the_date gets filled, but it takes another click to change the CSS properties.单击“x”时, the_date被填充,但需要再次单击才能更改 CSS 属性。 If I then click on another "x" without a the_date value, then the CSS properties change for the whole table.如果我然后单击另一个没有the_date值的“x”,则整个表的 CSS 属性都会更改。

How do I change the CSS properties on a click and also edit the table at the same time?如何单击更改 CSS 属性并同时编辑表格?

library(shiny)
library(DT)
library(lubridate)
rowNames <- TRUE # whether to show row names in the table
colIndex <- as.integer(rowNames)
callback <- c(
  sprintf("table.on('click', 'td:nth-child(%d)', function(){", colIndex+1),
  "  var td = this;",
  "  var cell = table.cell(td);",
  "  if(cell.data() === 'ok'){",
  "    cell.data('remove');",
  "  } else {",
  "    cell.data('ok');",
  "  }",
  "  var $row = $(td).closest('tr');",
  "  $row.toggleClass('excluded');",
  "  var excludedRows = [];",
  "  table.$('tr').each(function(i, row){",
  "    if($(this).hasClass('excluded')){",
  "      excludedRows.push(parseInt($(row).attr('id').split('_')[1]))",
  "    }",
  "  });",
  "  Shiny.setInputValue('excludedRows', excludedRows);",
  "})"
)
restore <- c(
  "function(e, table, node, config) {",
  "  table.$('tr').removeClass('excluded').each(function(){",
  sprintf("    var td = $(this).find('td').eq(%d)[0];", colIndex),
  "    var cell = table.cell(td);",
  "    cell.data('remove');",
  "  });",
  "  Shiny.setInputValue('excludedRows', null);",
  "}"
)
render <- c(
  'function(data, type, row, meta){',
  '  if(type === "display"){',
  '    var color = data === "remove" ? "red" : "forestgreen";',
  '    return "<span style=\\\"color:" + color +',
  '           "; font-size:18px\\\"><i class=\\\"glyphicon glyphicon-" +',
  '           data + "\\\"></i></span>";',
  '  } else {',
  '    return data;',
  '  }',
  '}'
)
ui <- fluidPage(
  tags$head(
    tags$style(HTML(
      ".excluded { color: rgb(211,211,211); font-style: italic; }"
    ))
  ),

  br(),
  DTOutput("mytable")
)
server <- function(input, output,session) {

  mcars <- mtcars[1:6,]
  mcars[,"the_date"] <- ""
  df <- cbind(Selected = "remove", mcars, id = paste0("row_",1:6))

  RV <- reactiveValues(data = df)


  output$mytable <- renderDataTable({
    datatable(isolate(RV$data), rownames = rowNames,
              extensions = c("Select", "Buttons"),
              selection = "none",
              callback = JS(callback),
              options = list(
                scrollY = "400px",
                paging = FALSE,
                rowId = JS(sprintf("function(df){return df[%d];}",
                                   ncol(df)-1+colIndex)),
                columnDefs = list(
                  list(visible = FALSE, targets = ncol(df)-1+colIndex),
                  list(className = "dt-center", targets = "_all"),
                  list(className = "notselectable", targets = colIndex),
                  list(targets = colIndex, render = JS(render))
                ),
                dom = "Bt",
                buttons = list("copy", "csv",
                               list(
                                 extend = "collection",
                                 text = 'Select all rows',
                                 action = JS(restore)
                               )
                ),
                select = list(style = "single",
                              selector = "td:not(.notselectable)")
              )
    )
  }, server = FALSE)


  observeEvent(input$excludedRows, {
    RV$data[as.integer(input$excludedRows), ]$the_date <- as.character.Date(today())
  })

}
shinyApp(ui, server)

Is it what you want?是你想要的吗?

library(shiny)
library(DT)

rowNames <- TRUE # whether to show row names in the table
colIndex <- as.integer(rowNames)

mcars <- mtcars[1:6,]
mcars[,"the_date"] <- ""
df <- cbind(Selected = "remove", mcars, id = paste0("row_",1:6))
colDate <- which(names(df) == "the_date")

callback <- c(
  sprintf("table.on('click', 'td:nth-child(%d)', function(){", colIndex+1),
  "  var td = this;",
  "  var cell = table.cell(td);",
  "  var $row = $(td).closest('tr');",
  sprintf("  var cell_date = table.cell($row[0], %d);", colDate + colIndex - 1),
  "  var today = new Date();",
  "  var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate();",
  "  if(cell.data() === 'ok'){",
  "    cell.data('remove');",
  "    cell_date.data('');",
  "  } else {",
  "    cell.data('ok');",
  "    cell_date.data(date);",
  "  }",
  "  $row.toggleClass('excluded');",
  "  var excludedRows = [];",
  "  table.$('tr').each(function(i, row){",
  "    if($(this).hasClass('excluded')){",
  "      excludedRows.push(parseInt($(row).attr('id').split('_')[1]))",
  "    }",
  "  });",
  "  Shiny.setInputValue('excludedRows', excludedRows);",
  "})"
)
restore <- c(
  "function(e, table, node, config) {",
  "  table.$('tr').removeClass('excluded').each(function(){",
  sprintf("    var td = $(this).find('td').eq(%d)[0];", colIndex),
  "    var cell = table.cell(td);",
  "    cell.data('remove');",
  "  });",
  "  Shiny.setInputValue('excludedRows', null);",
  "}"
)
render <- c(
  'function(data, type, row, meta){',
  '  if(type === "display"){',
  '    var color = data === "remove" ? "red" : "forestgreen";',
  '    return "<span style=\\\"color:" + color +',
  '           "; font-size:18px\\\"><i class=\\\"glyphicon glyphicon-" +',
  '           data + "\\\"></i></span>";',
  '  } else {',
  '    return data;',
  '  }',
  '}'
)
ui <- fluidPage(
  tags$head(
    tags$style(HTML(
      ".excluded { color: rgb(211,211,211); font-style: italic; }"
    ))
  ),

  br(),
  DTOutput("mytable")
)
server <- function(input, output,session) {

  output$mytable <- renderDataTable({
    datatable(df, rownames = rowNames,
              extensions = c("Select", "Buttons"),
              selection = "none",
              callback = JS(callback),
              options = list(
                scrollY = "400px",
                paging = FALSE,
                rowId = JS(sprintf("function(df){return df[%d];}",
                                   ncol(df)-1+colIndex)),
                columnDefs = list(
                  list(visible = FALSE, targets = ncol(df)-1+colIndex),
                  list(className = "dt-center", targets = "_all"),
                  list(className = "notselectable", targets = colIndex),
                  list(targets = colIndex, render = JS(render))
                ),
                dom = "Bt",
                buttons = list("copy", "csv",
                               list(
                                 extend = "collection",
                                 text = 'Select all rows',
                                 action = JS(restore)
                               )
                ),
                select = list(style = "single",
                              selector = "td:not(.notselectable)")
              )
    )
  }, server = FALSE)

}
shinyApp(ui, server)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM