这个想法是要有一个用户输入(访问代码),基于它可以访问不同的menuItem。因此,基本上,我们会根据用户要求提供自定义版本的应用。
3个menuItems的工作示例如下:
library(shiny)
library(shinydashboard)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = "SHOW/HIDE MULTIPLE MENU ITEMS"),
dashboardSidebar(
useShinyjs(),
sidebarMenu(
id = "tabs",
hidden(
menuItem("MENU ITEM 1", tabName = "mi1"),
menuItem("MENU ITEM 2", tabName = "mi2"),
menuItem("MENU ITEM 3", tabName = "mi3")
),
textInput(inputId = "accessToken", label = "Access Code", value = "Show/Hide Menu Items.")
)
),
dashboardBody()
)
server <- function (input, output, session){
observeEvent(input$accessToken,{
if(input$accessToken == "001"){
hide(selector = "ul li:eq(0)")
hide(selector = "ul li:eq(1)")
show(selector = "ul li:eq(2)")
} else if (input$accessToken == "010"){
hide(selector = "ul li:eq(0)")
show(selector = "ul li:eq(1)")
hide(selector = "ul li:eq(2)")
} else if (input$accessToken == "011"){
hide(selector = "ul li:eq(0)")
show(selector = "ul li:eq(1)")
show(selector = "ul li:eq(2)")
} else if (input$accessToken == "100"){
show(selector = "ul li:eq(0)")
hide(selector = "ul li:eq(1)")
hide(selector = "ul li:eq(2)")
} else if (input$accessToken == "101"){
show(selector = "ul li:eq(0)")
hide(selector = "ul li:eq(1)")
show(selector = "ul li:eq(2)")
} else if (input$accessToken == "110"){
show(selector = "ul li:eq(0)")
show(selector = "ul li:eq(1)")
hide(selector = "ul li:eq(2)")
} else if (input$accessToken == "111"){
show(selector = "ul li:eq(0)")
show(selector = "ul li:eq(1)")
show(selector = "ul li:eq(2)")
} else{
hide(selector = "ul li")
}
})
}
shinyApp(ui, server)
对于唯一访问代码可见的3个菜单项的所有组合,此方法都可以很好地工作。
但是您可以看到,这是访问3个menuItem的大量重复代码。
实际上我有10个甚至更多的menuItem,所以if else语句的总数将成倍增加。
我尝试过的内容:
我考虑过这种逻辑:对于10个menuItem,具有10位数字的访问代码,其中每个数字可以具有0(隐藏)或1(显示)的值。
observeEvent(input$accessToken, {
tokenStr <- input$accessToken
tokenStrShow <- which(strsplit(tokenStr, "")[[1]]=="1")
tokenStrHide <- which(strsplit(tokenStr, "")[[1]]=="0")
for (i in tokenStrShow){
# some logic to show all menuItems with value 1
# FOLLOWING DOESNOT WORK
# paste0("show(selector='ul li:eq(",i,")'")
}
})
我还遇到了我正在尝试实现的THIS JavaScript语言。但是我不知道如何在Shiny中做到这一点。
答案 0 :(得分:1)
这里是使用sidebarMenu
和renderUI
动态增长uiOutput
的想法。如果您增加了制表符的数量,那么转换为for循环也非常简单。
library(shiny)
library(shinydashboard)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(title = "SHOW/HIDE MULTIPLE MENU ITEMS"),
dashboardSidebar(
useShinyjs(),
uiOutput('sidebar'),
textInput(inputId = "accessToken", label = "Access Code", value = "Show/Hide Menu Items.")
),
dashboardBody()
)
server <- function (input, output, session){
output$sidebar <- renderUI({
menu_items = list()
if(substr(input$accessToken,1,1)=='1')
menu_items[[length(menu_items)+1]] = menuItem("MENU ITEM 1", tabName = "mi1")
if(substr(input$accessToken,2,2)=='1')
menu_items[[length(menu_items)+1]] = menuItem("MENU ITEM 2", tabName = "mi2")
if(substr(input$accessToken,3,3)=='1')
menu_items[[length(menu_items)+1]] = menuItem("MENU ITEM 3", tabName = "mi3")
print(menu_items)
sidebarMenu(id = "tabs",menu_items)
})
}
shinyApp(ui, server)
希望这会有所帮助!
答案 1 :(得分:1)
这是给将来的读者的。
弗洛里安的回答很有帮助,但由于我想将menuItem
保留在dashboardSidebar
中。
我花了一些时间,才意识到我在错误地使用paste0
。
我最终使用了以下内容:
observeEvent(input$accessToken, {
tokenStr <- strsplit(input$accessToken, "")[[1]]
tokenLen <- length(tokenStr)
if(tokenLen == 3){
tokenStrShow <- which(tokenStr=="1")
tokenStrHide <- which(tokenStr=="0")
for (i in tokenStrShow){
show(selector= paste0("ul li:eq(",i - 1,")"))
}
for (i in tokenStrHide){
hide(selector= paste0("ul li:eq(",i - 1,")"))
}
}
})
此方法的优点是:
tokenLen