使用客户端的afterChange事件更改rHandsontable的单元格背景

问题描述 投票:4回答:1

我想在用户端用户编辑了可动手操作单元格的背景颜色后,对其进行更改。该handontable是通过Shiny应用程序定义的;因此,这实际上是一个有关如何在Shiny应用程序中的rHandsontable中定义事件挂钩的问题。我要完成的一般用例是:用户编辑单元格数据;背景颜色更改以指示已更改并且正在等待保存到数据库中;更改被传递回Shiny的observeEvent();更改被发送到外部数据库并保存; rHandsontable将在输出上重新绘制,并且具有默认的背景色,该红色将删除更改后的颜色。结果是闪烁指示数据已保存。并且,如果发生数据库连接错误或其他问题,该颜色将持续存在,表明数据未保存。我已经能够完成一个工作示例,粘贴在下面。

特定问题:该挂钩当前是使用hot_col(1,renderer=change_hook)实现的,但这与渲染单元格无关,只是一种允许添加挂钩的方法。我假设hot_table()是正确的函数,但可以用来注册事件吗?更一般而言,是否有更内置的方法来完成此操作?

change_hook <- "
  function(instance, td, row, col, prop, value, cellProperties) {
Handsontable.hooks.add('afterChange', function(changes,source) { 
  if (source === 'edit' || source === 'undo' || source === 'autofill' || source === 'paste') {
    row = changes[0][0];
    col = changes[0][1];
    oldval = changes[0][2];
    newval = changes[0][3];

    if (oldval !== newval) {
      cell = this.getCell(row,col);
      cell.style.background = 'pink';
    }
  }
},instance);
Handsontable.renderers.TextRenderer.apply(this, arguments);
}"

ui <- div(width=300,rHandsontableOutput(outputId="hTable"))
server <- function(input, output, session) {

df<-data.frame(col1=c("Hands","on","Table"),col2=c(100,200,300),stringsAsFactors = F)
hTable <- reactiveVal(df)

observeEvent(input$hTable, {
withProgress(message = "Saving changes to database...", value=0.5, {

  Sys.sleep(1)

  incProgress(1, detail = "done")    
  input_hTable <- hot_to_r(input$hTable)
  hTable(input_hTable)
})
})

output$hTable <- renderRHandsontable({
rhandsontable(hTable(),stretchH="all",height=300) %>%
  hot_col(1,renderer=change_hook)
})
}
shinyApp(ui, server)
r shiny handsontable shinyjs rhandsontable
1个回答
0
投票

搜索了一会儿后,我已使用这些页面(handsontablehtmlwidgets)中的信息来更改已编辑单元格的背景颜色。

library(shiny)
library(rhandsontable)

change_hook <- "function(el,x) {
var hot = this.hot;  
var cellChanges = [];    

var changefn = function(changes,source) { 
if (source === 'edit' || source === 'undo' || source === 'autofill' || source === 'paste') {
row = changes[0][0];
col = changes[0][1];
oldval = changes[0][2];
newval = changes[0][3];
if (oldval !== newval) {
  var cell = hot.getCell(row, col);
  cell.style.background = 'pink';
  cellChanges.push({'rowid':row, 'colid':col});
}
}
}

var renderfn = function() {
for(i = 0; i < cellChanges.length; i++)
{
  var rowIndex = cellChanges[i]['rowid'];
  var columnIndex = cellChanges[i]['colid'];
  console.log(rowIndex);
  console.log(columnIndex);
  var cell = hot.getCell(rowIndex, columnIndex);
  if(cell !== null || cell !== undefined){
    cell.style.background = 'yellow';
  }
}
}

hot.addHook('afterChange', changefn);
hot.addHook('afterRender', renderfn);

}  "


ui <- div(rHandsontableOutput(outputId="hTable"))


server <- function(input, output, session) {      

  df<-data.frame(col1=c("Hands","on","Table"),col2=c(100,200,300),stringsAsFactors = F)

  hTable <- reactiveVal(df)

  output$hTable <- renderRHandsontable({

    rht = rhandsontable(hTable(),stretchH="all",height=300)%>%
hot_col('col1',readOnly=T)

    htmlwidgets::onRender(rht,change_hook)
  })
}

shinyApp(ui, server)
© www.soinside.com 2019 - 2024. All rights reserved.