R Shinydashboard-根据用户输入显示/隐藏多个菜单项

时间:2018-08-21 10:07:59

标签: javascript r shiny shinydashboard shinyjs

这个想法是要有一个用户输入(访问代码),基于它可以访问不同的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中做到这一点。

2 个答案:

答案 0 :(得分:1)

这里是使用sidebarMenurenderUI动态增长uiOutput的想法。如果您增加了制表符的数量,那么转换为for循环也非常简单。


enter image description here

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,")"))
  }
}

})

此方法的优点是:

  • 我能够将我的dashboardSidebar保持原样。 (这是我的项目所需要的)
  • 易于扩展,适用于越来越多的menuItem。 (仅需要编辑tokenLen
相关问题