Идея состоит в том, чтобы ввести пользовательский код (код доступа), на основе которого можно получить доступ к различным элементам меню. Таким образом, в основном у нас есть пользовательская версия приложения, доступная по требованию пользователя.
Рабочим примером для 3-х элементов меню является следующее:
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 элементам меню.
В действительности у меня есть 10 или даже большее количество элементов меню, поэтому в целом число операторов if else будет возрастать экспоненциально.
ЧТО Я ИСКЛЮЧАЮ:
Я подумал об этой логике: для 10 элементов меню есть код доступа 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,")'")
}
})
Я также наткнулся НАСТОЯЩИМ яваскрипт логики, я пытаюсь реализовать. Но я не знаю, как это сделать в Блестящем.
Вот идея для динамического роста вашего 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)
Надеюсь это поможет!
Это для будущих читателей.
Флорианский ответ был полезен, но так как я хотел сохранить свой пункт 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