在 shinydashboard 中动态创建可排序的 menuSubItems
Dynamically create sortable menuSubItems in shinydashboard
我有一个使用 shinydashboard
包的 Shiny 应用程序,我在其中动态地在 dashboardSidebar
的 sidebarMenu
中创建 menuSubItem
s。子项的创建由 actionButton 触发。我可以在服务器端很好地创建 menuSubItem
s,但我还想使用 sortable
包和 sortable_js
函数使它们可排序。不过,我似乎无法弄清楚将 sortable_js
函数放在哪里才能使它真正起作用。
这是我的 MRE:
library(shiny)
library(shinydashboard)
library(sortable)
# Define UI for shinydashboard
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("tab_one", tabName = "test_body"),
menuItemOutput("test"),
id = "sidebar"
)
),
dashboardBody(
tabItem("test_body",
actionButton("click_me", "Click Me"))
)
)
# Define server logic to dynamically create menuSubItems
server <- function(input, output) {
observeEvent(input$click_me, {
tabs_list <-
lapply(1:5, function(x) {
menuSubItem(text = paste("tab", x))
})
output$test <- renderMenu({
menuItem("test_tabs", do.call(tagList, tabs_list))
})
sortable_js("test_tabs")
})
}
# Run the application
shinyApp(ui = ui, server = server)
非常感谢任何帮助
sortable_js()
函数生成 HTML,因此需要将其包含在 UI 中。但是,您还必须确保它包含在它适用于已经存在的元素之后;否则它不会工作。在这里,我们可以通过将其作为使用 menuItem()
:
创建的菜单项的附加子项添加到 renderMenu()
调用的输出中来实现。
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
tagAppendChildren(menu, sortable_js("test_tabs"))
})
现在,您给 sortable_js()
的 ID 必须是您希望其子元素可排序的元素的 CSS ID。在这种情况下,这将是 menuItem()
内的 ul
元素,它包含所有子项。不幸的是,在创建菜单项时无法直接设置此 id,因此我们必须事后注入它。快速检查 menuItem()
源代码会发现 ul
标签是菜单项标签的第二个子标签:
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
menu$children[[2]] <- tagAppendAttributes(menu$children[[2]], id = "test_tabs")
tagAppendChildren(menu, sortable_js("test_tabs"))
})
通过这些修改,您的示例将会启动 运行:
library(shiny)
library(shinydashboard)
library(sortable)
# Define UI for shinydashboard
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("tab_one", tabName = "test_body"),
menuItemOutput("test")
)
),
dashboardBody(
tabItem("test_body", actionButton("click_me", "Click Me"))
)
)
# Define server logic to dynamically create menuSubItems
server <- function(input, output) {
observeEvent(input$click_me, {
tabs_list <- lapply(1:5, function(x) {
menuSubItem(text = paste("tab", x))
})
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
menu$children[[2]] <- tagAppendAttributes(menu$children[[2]], id = "test_tabs")
tagAppendChildren(menu, sortable_js("test_tabs"))
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
由 reprex package (v0.3.0)
于 2019-10-16 创建
我有一个使用 shinydashboard
包的 Shiny 应用程序,我在其中动态地在 dashboardSidebar
的 sidebarMenu
中创建 menuSubItem
s。子项的创建由 actionButton 触发。我可以在服务器端很好地创建 menuSubItem
s,但我还想使用 sortable
包和 sortable_js
函数使它们可排序。不过,我似乎无法弄清楚将 sortable_js
函数放在哪里才能使它真正起作用。
这是我的 MRE:
library(shiny)
library(shinydashboard)
library(sortable)
# Define UI for shinydashboard
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("tab_one", tabName = "test_body"),
menuItemOutput("test"),
id = "sidebar"
)
),
dashboardBody(
tabItem("test_body",
actionButton("click_me", "Click Me"))
)
)
# Define server logic to dynamically create menuSubItems
server <- function(input, output) {
observeEvent(input$click_me, {
tabs_list <-
lapply(1:5, function(x) {
menuSubItem(text = paste("tab", x))
})
output$test <- renderMenu({
menuItem("test_tabs", do.call(tagList, tabs_list))
})
sortable_js("test_tabs")
})
}
# Run the application
shinyApp(ui = ui, server = server)
非常感谢任何帮助
sortable_js()
函数生成 HTML,因此需要将其包含在 UI 中。但是,您还必须确保它包含在它适用于已经存在的元素之后;否则它不会工作。在这里,我们可以通过将其作为使用 menuItem()
:
renderMenu()
调用的输出中来实现。
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
tagAppendChildren(menu, sortable_js("test_tabs"))
})
现在,您给 sortable_js()
的 ID 必须是您希望其子元素可排序的元素的 CSS ID。在这种情况下,这将是 menuItem()
内的 ul
元素,它包含所有子项。不幸的是,在创建菜单项时无法直接设置此 id,因此我们必须事后注入它。快速检查 menuItem()
源代码会发现 ul
标签是菜单项标签的第二个子标签:
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
menu$children[[2]] <- tagAppendAttributes(menu$children[[2]], id = "test_tabs")
tagAppendChildren(menu, sortable_js("test_tabs"))
})
通过这些修改,您的示例将会启动 运行:
library(shiny)
library(shinydashboard)
library(sortable)
# Define UI for shinydashboard
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem("tab_one", tabName = "test_body"),
menuItemOutput("test")
)
),
dashboardBody(
tabItem("test_body", actionButton("click_me", "Click Me"))
)
)
# Define server logic to dynamically create menuSubItems
server <- function(input, output) {
observeEvent(input$click_me, {
tabs_list <- lapply(1:5, function(x) {
menuSubItem(text = paste("tab", x))
})
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
menu$children[[2]] <- tagAppendAttributes(menu$children[[2]], id = "test_tabs")
tagAppendChildren(menu, sortable_js("test_tabs"))
})
})
}
# Run the application
shinyApp(ui = ui, server = server)
由 reprex package (v0.3.0)
于 2019-10-16 创建