R Shiny复选框不会随observeEvent更新。

huangapple go评论65阅读模式
英文:

R Shiny checkboxes do not update with observeEvent

问题

我有一个带有复选框的Shiny数据表格。为了提供可复制的示例,我使用了iris数据集。在左侧的表格上,您可以点击复选框。右侧同时显示复选框的点击状态。到目前为止,这一切都运行得很好(列"select1"设置为TRUE)。

问题在于,在选择另一个物种作为输入并点击更新按钮后,右表格的内容会更新,但复选框的输出不会更新。复选框的选择输入在更新后保持不变。

这张图片显示了复选框的第一次选择,显示为"TRUE"在右表格中:

R Shiny复选框不会随observeEvent更新。

点击"Update"按钮后,右侧表格更新,但列"selected1"中的"TRUE"值保持不变:

R Shiny复选框不会随observeEvent更新。

这是我的示例应用程序:

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:
R Shiny复选框不会随observeEvent更新。
After clicking the Update button, the right table is updated, but the "TRUE" values in column "selected1" remain the same:
R Shiny复选框不会随observeEvent更新。

Here is my example app:

library(shiny)
library(DT)
species &lt;- c(&quot;setosa&quot;, &quot;versicolor&quot;, &quot;virginica&quot;)
shinyApp(
ui &lt;- navbarPage(
title = div(
HTML(paste0(&quot;&lt;br&gt;&lt;b&gt;&quot;,&quot;My Shiny Web-App&quot;,&quot;&lt;/b&gt;&quot;))
),
collapsible = TRUE,
tabPanel(
title =  h6(HTML(&quot;Tab1&quot;)),
(
fluidRow(
column(2,
sidebarPanel(
width = 12,
selectInput(
inputId = &quot;myTextInput1&quot;,
label = h5(&quot;Select species&quot;),
species
),
h5(&quot;Data&quot;),
actionButton(&quot;update&quot;,
&quot;Load / update data&quot;,
icon = icon(&quot;download&quot;),
style=&quot;color: #fff; background-color: #E74C3C&quot;)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
div(dataTableOutput(&quot;table&quot;), style = &quot;font-size:75%&quot;)
)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
tableOutput(&quot;table_download&quot;)
)
)
)
)
)
)
),
server&lt;-function(input, output, session) {
shinyInput&lt;-function(FUN, len, id, ...) {
inputs &lt;- character(len)
for (i in seq_len(len)) {
inputs[i] &lt;- as.character(FUN(paste0(id, i), label=NULL, ...))
}
inputs
}
shinyValue&lt;-function(id, len) {
unlist(lapply(seq_len(len), function(i) {
value &lt;- input[[paste0(id, i)]]
if (is.null(value)) FALSE else value
}))
}
rv1 &lt;- reactiveValues(bad=NULL,good=NULL)
observeEvent(input$update, {
rv1$data_filter = iris %&gt;% filter(Species == input$myTextInput1)
rv1$table = data.frame(
rv1$data_filter,
select1 = shinyInput(checkboxInput, nrow(rv1$data_filter), &#39;select_1&#39;, value=FALSE)
)
})
output$table &lt;- DT::renderDataTable({
DT::datatable({rv1$table},
selection = &quot;none&quot;,
escape = F,
rownames= FALSE,
options = list(
preDrawCallback=JS(&#39;function() { Shiny.unbindAll(this.api().table().node()); }&#39;),
drawCallback=JS(&#39;function() { Shiny.bindAll(this.api().table().node()); } &#39;),
autoWidth = T
)
)
}
)
table_download &lt;- reactive({
data.frame(
rv1$data_filter,
select1 = shinyValue(&#39;select_1&#39;, nrow(rv1$data_filter))
)
})
output$table_download &lt;- 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(&#39;function() { Shiny.unbindAll(this.api().table().node()); }&#39;),
drawCallback=JS(&#39;function() { Shiny.bindAll(this.api().table().node()); } &#39;)


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 &lt;- c(&quot;setosa&quot;, &quot;versicolor&quot;, &quot;virginica&quot;)
shinyApp(
ui &lt;- navbarPage(
tags$head(tags$script(
HTML(
&quot;Shiny.addCustomMessageHandler(&#39;unbindDT&#39;, function(id) {
var $table = $(&#39;#&#39;+id).find(&#39;table&#39;);
if($table.length &gt; 0){
Shiny.unbindAll($table.DataTable().table().node());
}
})&quot;)
)),
title = div(
HTML(paste0(&quot;&lt;br&gt;&lt;b&gt;&quot;,&quot;My Shiny Web-App&quot;,&quot;&lt;/b&gt;&quot;))
),
collapsible = TRUE,
tabPanel(
title =  h6(HTML(&quot;Tab1&quot;)),
(
fluidRow(
column(2,
sidebarPanel(
width = 12,
selectInput(
inputId = &quot;myTextInput1&quot;,
label = h5(&quot;Select species&quot;),
species
),
h5(&quot;Data&quot;),
actionButton(&quot;update&quot;,
&quot;Load / update data&quot;,
icon = icon(&quot;download&quot;),
style=&quot;color: #fff; background-color: #E74C3C&quot;)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
div(dataTableOutput(&quot;table&quot;), style = &quot;font-size:75%&quot;)
)
)
),
column(5,
mainPanel(
width = 3,
fluidPage(
tableOutput(&quot;table_download&quot;)
)
)
)
)
)
)
),
server&lt;-function(input, output, session) {
shinyInput&lt;-function(FUN, len, id, ...) {
inputs &lt;- character(len)
for (i in seq_len(len)) {
inputs[i] &lt;- as.character(FUN(paste0(id, i), label=NULL, ...))
}
inputs
}
shinyValue&lt;-function(id, len) {
unlist(lapply(seq_len(len), function(i) {
value &lt;- input[[paste0(id, i)]]
if (is.null(value)) FALSE else value
}))
}
rv1 &lt;- reactiveValues(bad=NULL,good=NULL)
observeEvent(input$update, {
session$sendCustomMessage(&quot;unbindDT&quot;, &quot;table&quot;)      
rv1$data_filter = iris %&gt;% filter(Species == input$myTextInput1)
rv1$table = data.frame(
rv1$data_filter,
select1 = shinyInput(checkboxInput, nrow(rv1$data_filter), &#39;select_1&#39;, value=FALSE)
)
})
output$table &lt;- DT::renderDataTable({
DT::datatable({rv1$table},
selection = &quot;none&quot;,
escape = F,
rownames= FALSE,
options = list(
preDrawCallback=JS(&#39;function() { Shiny.unbindAll(this.api().table().node()); }&#39;),
drawCallback=JS(&#39;function() { Shiny.bindAll(this.api().table().node()); } &#39;),
autoWidth = T
)
)
}
)
table_download &lt;- reactive({
data.frame(
rv1$data_filter,
select1 = shinyValue(&#39;select_1&#39;, nrow(rv1$data_filter))
)
})
output$table_download &lt;- renderTable({table_download()})
}
)

huangapple
  • 本文由 发表于 2023年4月17日 18:05:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/76033960.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定