在 rhandsontable 中插入重复的行

问题描述

我在 Shiny 仪表板中使用 rhandsontable 包,并希望在上下文菜单添加一个自定义的“复制行”选项,用户可以在其中复制一行并将重复的行插入表中(即,复制一个完整的行并在原始行下方插入副本)。这有助于防止错误并通过在新行中编辑较少的单元格来节省用户时间。不幸的是,我没有使用 JavaScript 的经验,也不确定如何创建此选项。我正在关注自定义菜单选项上的此相关 question,但尚未收到任何回复

如何添加自定义上下文菜单选项以复制表格行并将其插入下面的新行?感谢您的帮助!

Reprex


library(shiny)
library(shinyjs)
library(htmlwidgets)
library(tidyverse)
library(rhandsontable)
library(datasets)

ui <- fluidPage(
  titlePanel("Edit Iris"),mainPanel(rHandsontableOutput("iris_table"))
)

server <- function(input,output,session) {
  
  data(iris)
  summary(iris)
  
  copy_row_js <- "function (key,selection,clickEvent) {
                    this.alter('insert_row');
                    this.render();
                  }"
  
  output$iris_table <- renderRHandsontable({
    
    table <- rhandsontable(iris,rowHeaders = FALSE) %>%
      hot_context_menu(allowRowEdit = TRUE,allowColEdit = FALSE,customOpts = list(
                         copy_row = list(
                           name = "copy row",callback = htmlwidgets::JS(copy_row_js))
                       )
      )
    
    table
    
  })
  
}

shinyApp(ui = ui,server = server)

更新

我不知道如何将这个选项添加到上下文菜单中,所以我创建了一个“复制行”按钮来使用reactiveValues 实现相同的功能(作弊,但我需要一个解决方法)。这个关于访问 rhandsontable 值的 answer 非常有帮助。一项新挑战:在更改过滤器输入后,reactive() 过滤器突然没有重新运行。我创建了一个 reprex,但奇怪的是这个 reprex 似乎工作(?),因为虹膜数据集过滤器在更改所选物种输入后重新运行。更复杂的应用程序中的过滤器不会重新运行。关于可能发生的事情有什么建议吗?

library(shiny)
library(shinyjs)
library(htmlwidgets)
library(tidyverse)
library(rhandsontable)
library(datasets)

data("iris")
summary(iris)

ui <- fluidPage(
  titlePanel("Edit Iris"),sidebarLayout(
    sidebarPanel(
      selectizeInput("iris_species","Iris Species",choices = iris$Species,multiple = FALSE,selected = (iris$Species == "setosa")),br(),actionButton("copy_row","copy Row"),actionButton("reset","Reset"),),mainPanel(rHandsontableOutput("iris_table"))
  )
)

server <- function(input,session) {
  
  data("iris")
  summary(iris)
  
  df <- reactive({
    
    input$iris_species
    
    data("iris")
    summary(iris)
    
    df <- iris %>%
      filter(Species == input$iris_species) %>%
      arrange(Species,Sepal.Length)
    df
  })
  
  iris_values <- reactiveValues(data = as.data.frame(NULL))
  
  # Beginning state: filter data by input$iris_species
  observeEvent(input$iris_species,{
      iris_values$data <- df()
  })
  
  # Reset to initially displayed df(),deleting any user changes
  observeEvent(input$reset,{
    iris_values$data <- df()
  })
  
  # copy row for additional Sepal.Length entries by user
  observeEvent(input$copy_row,{
    
    row_select <- input$iris_table_select$select$r
    
    copy_row <- as.data.frame(hot_to_r(req(input$iris_table))) %>%
      slice(row_select)
    
    iris_values$data <- as.data.frame(hot_to_r(req(input$iris_table))) %>%
      bind_rows(copy_row) %>%
      arrange(Species,Sepal.Length)
  })
  
  # Output handsontable
  output$iris_table <- renderRHandsontable({
    
    table <- rhandsontable({iris_values$data},rowHeaders = FALSE,height = 500,width = 1000,selectCallback = TRUE) %>%
      hot_context_menu(allowRowEdit = TRUE,allowColEdit = FALSE
      )
    
    table

  })
}

shinyApp(ui = ui,server = server)

解决

一直在寻找“不重新运行”问题的答案,并发现了这个 answer,描述了依赖于已验证反应的可能不会传递验证错误。成功!我发现“复制”按钮非常有用 - 随时发布以备不时之需。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)