英文:
R/Shiny Javascript passing arguments directly from R
问题
我有一个使用rhandsontable的Shiny App,我希望在修改值后更改单元格的颜色。
基本上,我需要对Kat在这里提供的解决方案进行一些修改:https://stackoverflow.com/questions/73337727/in-shiny-rhandsontable-afterchange-change-multiple-cell-backgrounds-at-once/73347195#73347195。
我想要的是,根据发生更改的行的不同,有不同的颜色。我在下面实现了一个示例,在前5行中颜色是蓝色,在其余行中是粉色。但我需要帮助的地方是,如何通过R动态地将参数传递给javascript中的数组?
(因为我每次都需要不同的行,并且我希望从R中获取所需的行索引,例如通过which
,然后在R中有一个向量,应该自动传递给下面的javascript函数,而不是现在的if (elem['rowind'] in [0,1,2,4])
)
library(shiny)
library(rhandsontable)
change_hook <- "function(el,x) {
hot = this.hot;
cellchngs = [];
afterChange = function(changes, source) {
$.each(changes, function (index, elem) {
change = elem; /* gather the row, col, old, new values */
if(change[2] !== change[3]) { /* if old isn't the same as new */
cellchg = ({rowind: change[0], colind: change[1]});
cellchngs.push(cellchg); /* add row and column indicies to array */
}
});
$.each(cellchngs, function(ind, elem) {
td = hot.getCell(elem['rowind'], elem['colind']); /* get the html element */
if (elem['rowind'] in [0,1,2,4]){
td.style.background = 'cyan'; /* set background color */
}
else {
td.style.background = 'pink'; /* set background color */
}
});
}
hot.addHook('afterChange', afterChange); /* add event to table */
}"
ui <- div(actionButton(inputId = "reset_button",label = "Reset")
,rHandsontableOutput(outputId="mtcars"))
server <- function(input, output, session) {
reset <- reactiveVal(0)
output$mtcars <- renderRHandsontable({
r = reset()
rht = rhandsontable(mtcars,reset=r,stretchH="all",height=300)
reset(0)
htmlwidgets::onRender(rht,change_hook)
})
observeEvent(input$reset_button,
{
reset(1)
})
}
shinyApp(ui, server)
英文:
I have a Shiny App with rhandsontable where I want the cell colors to be changed after a value is modified
Basically I needed some modification of Kat's solution implemented here https://stackoverflow.com/questions/73337727/in-shiny-rhandsontable-afterchange-change-multiple-cell-backgrounds-at-once/73347195#73347195.
what I want, are different colors based on the row where the change has occurred. I have implemented an example below where in the first 5 rows the color is blue and pink in the rest, but where I would need help, how can I pass a paramter for the array in javascript dynamically via R?
(Because I need different rows everytime and I would like to get the desired row indices from R for example via ?which, then have a vector in R which should ideally automatically be passed to the javascript function below instead of the if (elem['rowind'] in [0,1,2,4])
as it is now)
library(shiny)
library(rhandsontable)
change_hook <- "function(el,x) {
hot = this.hot;
cellchngs = [];
afterChange = function(changes, source) {
$.each(changes, function (index, elem) {
change = elem; /* gather the row, col, old, new values */
if(change[2] !== change[3]) { /* if old isn't the same as new */
cellchg = ({rowind: change[0], colind: change[1]});
cellchngs.push(cellchg); /* add row and column indicies to array */
}
});
$.each(cellchngs, function(ind, elem) {
td = hot.getCell(elem['rowind'], elem['colind']); /* get the html element */
if (elem['rowind'] in [0,1,2,4]){
td.style.background = 'cyan'; /* set background color */
}
else {
td.style.background = 'pink'; /* set background color */
}
});
}
hot.addHook('afterChange', afterChange); /* add event to table */
}"
ui <- div(actionButton(inputId = "reset_button",label = "Reset")
,rHandsontableOutput(outputId="mtcars"))
server <- function(input, output, session) {
reset <- reactiveVal(0)
output$mtcars <- renderRHandsontable({
r = reset()
rht = rhandsontable(mtcars,reset=r,stretchH="all",height=300)
reset(0)
htmlwidgets::onRender(rht,change_hook)
})
observeEvent(input$reset_button,
{
reset(1)
})
}
shinyApp(ui, server)
答案1
得分: 2
我会使用onRender
的data
参数(参见?htmlwidgets::onRender
)。它允许在JavaScript函数中使用第三个参数:即data
参数,它是一个转换为JavaScript的R对象。
change_hook <- "function(el, x, v) {
hot = this.hot;
cellchngs = [];
afterChange = function(changes, source) {
$.each(changes, function (index, elem) {
change = elem; /* 收集行、列、旧值、新值 */
if(change[2] !== change[3]) { /* 如果旧值与新值不同 */
cellchg = ({rowind: change[0], colind: change[1]});
cellchngs.push(cellchg); /* 将行和列索引添加到数组中 */
}
});
$.each(cellchngs, function(ind, elem) {
td = hot.getCell(elem['rowind'], elem['colind']); /* 获取HTML元素 */
if(v.indexOf(elem['rowind']) > -1) {
td.style.background = 'cyan'; /* 设置背景颜色 */
} else {
td.style.background = 'pink'; /* 设置背景颜色 */
}
});
}
hot.addHook('afterChange', afterChange); /* 将事件添加到表格中 */
}"
然后执行:
htmlwidgets::onRender(rht, change_hook, c(0, 1, 2, 4))
英文:
I would use the data
argument of onRender
(see ?htmlwidgets::onRender
). It allows to use a third argument in the JavaScript function: namely this data
argument, a R object, converted to JavaScript.
change_hook <- "function(el, x, v) {
hot = this.hot;
cellchngs = [];
afterChange = function(changes, source) {
$.each(changes, function (index, elem) {
change = elem; /* gather the row, col, old, new values */
if(change[2] !== change[3]) { /* if old isn't the same as new */
cellchg = ({rowind: change[0], colind: change[1]});
cellchngs.push(cellchg); /* add row and column indicies to array */
}
});
$.each(cellchngs, function(ind, elem) {
td = hot.getCell(elem['rowind'], elem['colind']); /* get the html element */
if(v.indexOf(elem['rowind']) > -1) {
td.style.background = 'cyan'; /* set background color */
} else {
td.style.background = 'pink'; /* set background color */
}
});
}
hot.addHook('afterChange', afterChange); /* add event to table */
}"
and then:
htmlwidgets::onRender(rht, change_hook, c(0, 1, 2, 4))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论