cod*_*boy 4 r shiny shinydashboard sortablejs
我用一个闪亮的应用程序shinydashboard中,我动态创建包menuSubItem在SsidebarMenu的dashboardSidebar。子项的创建由 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)
Run Code Online (Sandbox Code Playgroud)
任何帮助深表感谢
该sortable_js()函数生成 HTML,因此需要将其包含在 UI 中。但是,您还必须确保它包含在它所应用的元素已经存在之后;否则它不会工作。在这里,我们可以通过将它添加到renderMenu()调用的输出中来实现这一点,作为使用创建的菜单项的附加子项menuItem():
output$test <- renderMenu({
menu <- menuItem("test_tabs", do.call(tagList, tabs_list))
tagAppendChildren(menu, sortable_js("test_tabs"))
})
Run Code Online (Sandbox Code Playgroud)
现在,您提供的 idsortable_js()必须是您想要对其子项进行排序的元素的 CSS id。在这种情况下,这将是 中的ul元素menuItem(),其中包含所有子项。不幸的是,在创建菜单项时无法直接设置此 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"))
})
Run Code Online (Sandbox Code Playgroud)
通过这些修改,您的示例将启动并运行:
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)
Run Code Online (Sandbox Code Playgroud)
由reprex 包(v0.3.0)于 2019 年 10 月 16 日创建