В настоящее время есть следующий код - есть ли способ сбросить все checkboxes
в этом приложении - независимо от того, выбран ли он на одной вкладке - или на нескольких вкладках?
Итак, я также ввел в приложение кнопку выбора и отмены выбора всех, так что, надеюсь, эта функция все еще останется там?
код:
library(shiny)
library(shinydashboard)
library(tidyverse)
library(magrittr)
header <- dashboardHeader(
title = "My Dashboard",
titleWidth = 500
)
siderbar <- dashboardSidebar(
sidebarMenu(
# Add buttons to choose the way you want to select your data
radioButtons("select_by", "Select by:",
c("Food Type" = "Food",
"Gym Type" = "Gym",
"TV show" = "TV"))
)
)
body <- dashboardBody(
fluidRow(
uiOutput("Output_panel")
),
tabBox(title = "RESULTS", width = 12,
tabPanel("Visualisation",
width = 12,
height = 800
)
)
)
ui <- dashboardPage(header, siderbar, body, skin = "purple")
server <- function(input, output, session){
nodes_data_1 <- data.frame(id = 1:15,
Food = as.character(c("Edibles", "Fried", "Home Cooked", "packaged", "vending machine")),
Product_name = as.character(c("Bacon", "Cheese", "eggs", "chips", "beans", "oast", "oats and beans", "fried beans", "chickpeas", "broad beans", "garbanzo", "oat bars", "dog meat", "cat food", "horse meat")),
Gym_type = as.character(paste("Gym", 1:15)), TV =
sample(LETTERS[1:3], 15, replace = TRUE))
# build a edges dataframe
edges_data_1 <- data.frame(from = trunc(runif (15)*(15-1))+1,
to = trunc(runif (15)*(15-1))+1)
# create reactive of nodes
nodes_data_reactive <- reactive({
nodes_data_1
}) # end of reactive
# create reacive of edges
edges_data_reactive <- reactive({
edges_data_1
}) # end of reactive
# The output panel differs depending on the how the data is selected
# so it needs to be in the server section, not the UI section and created
# with renderUI as it is reactive
output$Output_panel <- renderUI({
# When selecting by workstream and issues:
if (input$select_by == "Food") {
box(title = "Output PANEL",
collapsible = TRUE,
width = 12,
do.call(tabsetPanel, c(id='t',lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
food <- unique(sort(as.character(nodes_data_reactive()$Food)))
tabPanel(food[i],
checkboxGroupInput(paste0("checkboxfood_", i),
label = NULL,
choices = nodes_data_reactive() %>%
filter(Food == food[i]) %>%
select(Product_name) %>%
unlist(use.names = FALSE)),
checkboxInput(paste0("all_", i), "Select all", value = TRUE)
)
})))
) # end of Tab box
# When selecting by the strength of links connected to the issues:
} else if (input$select_by == "Gym") {
box(title = "Output PANEL", collapsible = TRUE, width = 12,
checkboxGroupInput("select_gyms", "Select gyms you want to display", choices = unique(nodes_data_reactive()$Gym_type)
,
selected = NULL,
inline = FALSE
)# end of checkboxGroupInput
) # end of box
} else if (input$select_by == "TV") {
box(title = "Output PANEL", collapsible = TRUE, width = 12,
checkboxGroupInput("select_tvs",
"Select the tv shows you want to see",choices = sort(unique(nodes_data_reactive()$TV)),
selected = NULL,
inline = FALSE
)# end of checkboxGroupInput
) # end of box
} # end of else if
}) # end of renderUI
observe({
lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
food <- unique(sort(as.character(nodes_data_reactive()$Food)))
product_choices <- nodes_data_reactive() %>%
filter(Food == food[i]) %>%
select(Product_name) %>%
unlist(use.names = FALSE)
if (!is.null(input[[paste0("all_", i)]])){
if (input[[paste0("all_", i)]] == TRUE) {
updateCheckboxGroupInput(session,
paste0("checkboxfood_", i),
label = NULL,
choices = product_choices,
selected = product_choices)
} else {
updateCheckboxGroupInput(session,
paste0("checkboxfood_", i),
label = NULL,
choices =product_choices)
}
}
})
})
} # end of server
# Run the application
shinyApp(ui = ui, server = server)
Я не могу отображать элементы пользовательского интерфейса вне функции сервера, так как я хотел бы, чтобы элементы генерировались через сервер - также мне нужно, чтобы постоянное наблюдение работало как единственный способ узнать, какие флажки были выбраны?
Если вы не можете избежать renderUI
, ничего страшного. Но если updateCheckboxGroupInput
следует применять только в ответ на нажатие кнопки, используйте observeEvent(input$button_id, ...)
. Именно для этого и создан observeEvent
.
Вот решение, основанное на фиксированном соглашении об именах для ваших флажков (я добавил префикс "chk _")
Обновлено: различать updateCheckboxInput и updateCheckboxGroupInput
library(shiny)
library(shinydashboard)
library(tidyverse)
library(magrittr)
header <- dashboardHeader(
title = "My Dashboard",
titleWidth = 500
)
siderbar <- dashboardSidebar(
sidebarMenu(
# Add buttons to choose the way you want to select your data
radioButtons("select_by", "Select by:",
c("Food Type" = "Food",
"Gym Type" = "Gym",
"TV show" = "TV"))
)
)
body <- dashboardBody(
fluidRow(
uiOutput("Output_panel"),
tabBox(title = "RESULTS", width = 12,
tabPanel("Visualisation",
br(),
width = 12,
height = 800
)
),
column(12, actionButton(inputId = "resetBtn", label = "Reset Selection", icon = icon("times-circle")))
)
)
ui <- dashboardPage(header, siderbar, body, skin = "purple")
server <- function(input, output, session){
nodes_data_1 <- data.frame(id = 1:15,
Food = as.character(c("Edibles", "Fried", "Home Cooked", "packaged", "vending machine")),
Product_name = as.character(c("Bacon", "Cheese", "eggs", "chips", "beans", "oast", "oats and beans", "fried beans", "chickpeas", "broad beans", "garbanzo", "oat bars", "dog meat", "cat food", "horse meat")),
Gym_type = as.character(paste("Gym", 1:15)), TV =
sample(LETTERS[1:3], 15, replace = TRUE))
# build a edges dataframe
edges_data_1 <- data.frame(from = trunc(runif (15)*(15-1))+1,
to = trunc(runif (15)*(15-1))+1)
# create reactive of nodes
nodes_data_reactive <- reactive({
nodes_data_1
}) # end of reactive
# create reacive of edges
edges_data_reactive <- reactive({
edges_data_1
}) # end of reactive
# The output panel differs depending on the how the data is selected
# so it needs to be in the server section, not the UI section and created
# with renderUI as it is reactive
output$Output_panel <- renderUI({
# When selecting by workstream and issues:
if (input$select_by == "Food") {
box(title = "Output PANEL",
collapsible = TRUE,
width = 12,
do.call(tabsetPanel, c(id='t',lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
food <- unique(sort(as.character(nodes_data_reactive()$Food)))
tabPanel(food[i],
checkboxGroupInput(paste0("chkgrp_checkboxfood_", i),
label = NULL,
choices = nodes_data_reactive() %>%
filter(Food == food[i]) %>%
select(Product_name) %>%
unlist(use.names = FALSE)),
checkboxInput(paste0("chksingle_all_", i), "Select all", value = TRUE)
)
})))
) # end of Tab box
# When selecting by the strength of links connected to the issues:
} else if (input$select_by == "Gym") {
box(title = "Output PANEL", collapsible = TRUE, width = 12,
checkboxGroupInput("chkgrp_select_gyms", "Select gyms you want to display", choices = unique(nodes_data_reactive()$Gym_type)
,
selected = NULL,
inline = FALSE
)# end of checkboxGroupInput
) # end of box
} else if (input$select_by == "TV") {
box(title = "Output PANEL", collapsible = TRUE, width = 12,
checkboxGroupInput("chkgrp_select_tvs",
"Select the tv shows you want to see",choices = sort(unique(nodes_data_reactive()$TV)),
selected = NULL,
inline = FALSE
)# end of checkboxGroupInput
) # end of box
} # end of else if
}) # end of renderUI
observe({
lapply(1:length(unique(nodes_data_reactive()$Food)), function(i) {
food <- unique(sort(as.character(nodes_data_reactive()$Food)))
product_choices <- nodes_data_reactive() %>%
filter(Food == food[i]) %>%
select(Product_name) %>%
unlist(use.names = FALSE)
if (!is.null(input[[paste0("chksingle_all_", i)]])){
if (input[[paste0("chksingle_all_", i)]] == TRUE) {
updateCheckboxGroupInput(session,
paste0("chkgrp_checkboxfood_", i),
label = NULL,
choices = product_choices,
selected = product_choices)
} else {
updateCheckboxGroupInput(session,
paste0("chkgrp_checkboxfood_", i),
label = NULL,
choices =product_choices)
}
}
})
})
observeEvent(input$resetBtn, ignoreNULL = TRUE, ignoreInit = TRUE, {
resetChksingleInputs <- names(input)[grepl("^chksingle*", names(input))]
cat("Resetting single checkboxes:", resetChksingleInputs, sep = "\n")
lapply(resetChksingleInputs, updateCheckboxInput, session=session, value = FALSE)
resetChkgrpInputs <- names(input)[grepl("^chkgrp*", names(input))]
cat("Resetting checkbox groups:", resetChkgrpInputs, sep = "\n")
lapply(resetChkgrpInputs, updateCheckboxGroupInput , session=session, selected = character(0))
})
} # end of server
# Run the application
shinyApp(ui = ui, server = server)
Спасибо за ввод - однако это не сбрасывает флажки, когда вы выбираете их на разных вкладках, только когда вы нажимаете выбрать все на отдельной вкладке - в основном потому, что вместо этого должно быть наблюдение, которое постоянно выполняется?
Я не совсем понимаю, о чем вы. На моей машине все вкладки очищены.
Сейчас я пишу для вас подробный ответ ниже
Хорошо, 0 - если вы нажмете кнопку первоначального сброса всех, он установит, что все не выбрано, поскольку оно начинается со всех выбранных - теперь, если вы нажмете 2 флажка на первой вкладке, а затем 2 на следующей вкладке - затем нажмите кнопку сброса всех не сбрасывает эти флажки как «не выбранные», а оставляет их такими, какие они «выбраны»
Ах да, понятно. Нам нужно различать checkboxInput
и checkboxGroupInput
- пожалуйста, посмотрите мою правку. Возможно, вы захотите заключить процедуру сброса в функцию, чтобы избежать повторения кода (в настоящее время мало времени).
Спасибо за вклад! действительно полезно увидеть, как это работает - я думаю, что функция для завершения кода была бы следующим логическим шагом
Просто интересно, были ли у вас какие-либо мысли о следующей ситуации в приложении: если вы установите несколько флажков на одной панели вкладок, затем переключите панели вкладок и нажмите «выбрать все», он будет использовать оператор Dplyr и сохранит эту информацию и будет использовать ее как те. флажки, которые вы выбрали, поскольку он считает, что это будет первый случай - есть ли способ обойти это? Я использовал изолирующие, реактивные значения и даже обернул на него оператор ifelse, но не повезло - больше информации для сценария ниже!
Например - Запустите приложение - Нажмите кнопку Сбросить все флажки - Теперь посмотрите следующее поведение - На вкладке «съедобные» установите флажок «бекон», переключите вкладки и перейдите на вкладку «Жареные» и установите флажок "кнопка" Выбрать все "- это снимает флажок" отмеченный "бекон, который мы изначально установили, и использует вкладку" Жареный "как первый случай нажатия чего-либо - конечно, вы можете проверить все, что захотите, после этого, но это поведение ошибочно, потому что этого первого оператора Dplyr - любые обходные пути - перепробовали почти все, что я мог придумать!
У вас точно такое же поведение в исходном коде. Соответственно, я думаю, вам следует задать еще один вопрос по этому поводу. Здесь было предложено сбросить все флажки - это то, что я вам предоставил. PS: проблема будет в сочетании observe
(прослушивание всех изменений) и updateCheckboxGroupInput
.
действительно было бы! спасибо за помощь - я принял ответ, но этот вопрос закрыт, насколько я могу судить!
updateCheckboxGroupInput
должен работать нормально, если вы избавитесь отrenderUI
. Вообще говоря,renderUI
с виджетами ввода может доставить вам множество неприятностей, и его следует использовать только тогда, когда это абсолютно необходимо. Также попробуйте использоватьobserveEvent
вместоobserve
. Это улучшает читаемость и позволяет избежать нежелательных побочных эффектов в долгосрочной перспективе.