英文:
R Shiny checkboxes do not update with observeEvent
问题
我有一个带有复选框的Shiny数据表格。为了提供可复制的示例,我使用了iris
数据集。在左侧的表格上,您可以点击复选框。右侧同时显示复选框的点击状态。到目前为止,这一切都运行得很好(列"select1"设置为TRUE)。
问题在于,在选择另一个物种作为输入并点击更新按钮后,右表格的内容会更新,但复选框的输出不会更新。复选框的选择输入在更新后保持不变。
这张图片显示了复选框的第一次选择,显示为"TRUE"在右表格中:
点击"Update"按钮后,右侧表格更新,但列"selected1"中的"TRUE"值保持不变:
这是我的示例应用程序:
library(shiny)
library(DT)
species <- c("setosa", "versicolor", "virginica")
shinyApp(
ui <- navbarPage(
title = div(
HTML(paste0("<br><b>","My Shiny Web-App","</b>"))
),
collapsible = TRUE,
tabPanel(
title = h6(HTML("Tab1")),
(
fluidRow(
column(2,
sidebarPanel(
width = 12,
selectInput(
inputId = "myTextInput1",
label = h5("Select species"),
species
),
h5("Data"),
actionButton("update",
"Load / update data",
icon = icon("download"),
style="color: #fff; background-color: #E74C3C")
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
div(dataTableOutput("table"), style = "font-size:75%")
)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
tableOutput("table_download")
)
)
)
)
)
)
),
server<-function(input, output, session) {
shinyInput<-function(FUN, len, id, ...) {
inputs <- character(len)
for (i in seq_len(len)) {
inputs[i] <- as.character(FUN(paste0(id, i), label=NULL, ...))
}
inputs
}
shinyValue<-function(id, len) {
unlist(lapply(seq_len(len), function(i) {
value <- input[[paste0(id, i)]]
if (is.null(value)) FALSE else value
}))
}
rv1 <- reactiveValues(bad=NULL,good=NULL)
observeEvent(input$update, {
rv1$data_filter = iris %>% filter(Species == input$myTextInput1)
rv1$table = data.frame(
rv1$data_filter,
select1 = shinyInput(checkboxInput, nrow(rv1$data_filter), 'select_1', value=FALSE)
)
})
output$table <- DT::renderDataTable({
DT::datatable({rv1$table},
selection = "none",
escape = F,
rownames= FALSE,
options = list(
preDrawCallback=JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback=JS('function() { Shiny.bindAll(this.api().table().node()); } ')
)
)
}
)
table_download <- reactive({
data.frame(
rv1$data_filter,
select1 = shinyValue('select_1', nrow(rv1$data_filter))
)
})
output$table_download <- renderTable({table_download()})
}
)
我希望复选框的输出在点击按钮时自动更新。我猜想这个问题可能与以下选项有关:
preDrawCallback=JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback=JS('function() { Shiny.bindAll(this.api().table().node()); } ')
有人可以帮助我吗?非常感谢!
英文:
I have a datatable with checkboxes in Shiny. For my reproducible example I took the iris
dataset.
On the table on the left side you can click on the checkboxes. On the right side it is shown simultaneously whether a checkbox is clicked. This works quite well so far (column "select1" is set to TRUE).
The problem is that after selecting another species as input and clicking on the update button, the content of right table is updated, but not the output of the checkboxes. The selected input of the checkboxes remains the same after the update.
This picture shows the first selection of the checkboxes, which is displayed as "TRUE" on the right table:
After clicking the Update button, the right table is updated, but the "TRUE" values in column "selected1" remain the same:
Here is my example app:
library(shiny)
library(DT)
species <- c("setosa", "versicolor", "virginica")
shinyApp(
ui <- navbarPage(
title = div(
HTML(paste0("<br><b>","My Shiny Web-App","</b>"))
),
collapsible = TRUE,
tabPanel(
title = h6(HTML("Tab1")),
(
fluidRow(
column(2,
sidebarPanel(
width = 12,
selectInput(
inputId = "myTextInput1",
label = h5("Select species"),
species
),
h5("Data"),
actionButton("update",
"Load / update data",
icon = icon("download"),
style="color: #fff; background-color: #E74C3C")
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
div(dataTableOutput("table"), style = "font-size:75%")
)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
tableOutput("table_download")
)
)
)
)
)
)
),
server<-function(input, output, session) {
shinyInput<-function(FUN, len, id, ...) {
inputs <- character(len)
for (i in seq_len(len)) {
inputs[i] <- as.character(FUN(paste0(id, i), label=NULL, ...))
}
inputs
}
shinyValue<-function(id, len) {
unlist(lapply(seq_len(len), function(i) {
value <- input[[paste0(id, i)]]
if (is.null(value)) FALSE else value
}))
}
rv1 <- reactiveValues(bad=NULL,good=NULL)
observeEvent(input$update, {
rv1$data_filter = iris %>% filter(Species == input$myTextInput1)
rv1$table = data.frame(
rv1$data_filter,
select1 = shinyInput(checkboxInput, nrow(rv1$data_filter), 'select_1', value=FALSE)
)
})
output$table <- DT::renderDataTable({
DT::datatable({rv1$table},
selection = "none",
escape = F,
rownames= FALSE,
options = list(
preDrawCallback=JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback=JS('function() { Shiny.bindAll(this.api().table().node()); } '),
autoWidth = T
)
)
}
)
table_download <- reactive({
data.frame(
rv1$data_filter,
select1 = shinyValue('select_1', nrow(rv1$data_filter))
)
})
output$table_download <- renderTable({table_download()})
}
)
I want the output of the checkboxes to update automatically with the click on the button.
My guess is that this problem might be due to the following options:
preDrawCallback=JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback=JS('function() { Shiny.bindAll(this.api().table().node()); } ')
Can anyone help me?
Many thanks in advance!
答案1
得分: 0
我能应用这个答案到我的情况并解决我的问题:
https://stackoverflow.com/questions/68555784/issue-in-action-button-when-clicked/68560286
英文:
I was able to apply this answer to my case and solve my problem:
https://stackoverflow.com/questions/68555784/issue-in-action-button-when-clicked/68560286
library(shiny)
library(DT)
species <- c("setosa", "versicolor", "virginica")
shinyApp(
ui <- navbarPage(
tags$head(tags$script(
HTML(
"Shiny.addCustomMessageHandler('unbindDT', function(id) {
var $table = $('#'+id).find('table');
if($table.length > 0){
Shiny.unbindAll($table.DataTable().table().node());
}
})")
)),
title = div(
HTML(paste0("<br><b>","My Shiny Web-App","</b>"))
),
collapsible = TRUE,
tabPanel(
title = h6(HTML("Tab1")),
(
fluidRow(
column(2,
sidebarPanel(
width = 12,
selectInput(
inputId = "myTextInput1",
label = h5("Select species"),
species
),
h5("Data"),
actionButton("update",
"Load / update data",
icon = icon("download"),
style="color: #fff; background-color: #E74C3C")
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
div(dataTableOutput("table"), style = "font-size:75%")
)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
tableOutput("table_download")
)
)
)
)
)
)
),
server<-function(input, output, session) {
shinyInput<-function(FUN, len, id, ...) {
inputs <- character(len)
for (i in seq_len(len)) {
inputs[i] <- as.character(FUN(paste0(id, i), label=NULL, ...))
}
inputs
}
shinyValue<-function(id, len) {
unlist(lapply(seq_len(len), function(i) {
value <- input[[paste0(id, i)]]
if (is.null(value)) FALSE else value
}))
}
rv1 <- reactiveValues(bad=NULL,good=NULL)
observeEvent(input$update, {
session$sendCustomMessage("unbindDT", "table")
rv1$data_filter = iris %>% filter(Species == input$myTextInput1)
rv1$table = data.frame(
rv1$data_filter,
select1 = shinyInput(checkboxInput, nrow(rv1$data_filter), 'select_1', value=FALSE)
)
})
output$table <- DT::renderDataTable({
DT::datatable({rv1$table},
selection = "none",
escape = F,
rownames= FALSE,
options = list(
preDrawCallback=JS('function() { Shiny.unbindAll(this.api().table().node()); }'),
drawCallback=JS('function() { Shiny.bindAll(this.api().table().node()); } '),
autoWidth = T
)
)
}
)
table_download <- reactive({
data.frame(
rv1$data_filter,
select1 = shinyValue('select_1', nrow(rv1$data_filter))
)
})
output$table_download <- renderTable({table_download()})
}
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论