I'm trying to implement a reactive text for a shinydashboard
menuItem
without having to use renderMenu
in the server
. The reason is that every time the menu is rendered, it resets all items in the menu to default. However, some of them are also reactive, e.g. an actionbutton
being disabled upon an event.
I suspect this might be possible with runjs
, but I don't know how to properly address just the text of a menu item of a specific id. I wasn't able to use isolate
for the things I didn't want to be reactive in renderMenu
; I was getting errors when I tried that.
This below example is not desired, as each time the menu is rendered, it resets everything, regardless of how the items had subsequently been changed. In this example, the button and checkbox are reset to an enabled
state, despite disabling them upon button click. In contrast and to illustrate what I mean, the button and checkbox in menu 1 remain disabled.
library(shiny)
library(shinydashboard)
library(shinyjs)
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(
sidebarMenu(
menuItem(
"Menu1",
actionButton("dummy1", "Dummy Button 1"),
checkboxInput('dummy3', 'Dummy 3')
),
menuItemOutput('menu2')
)
),
dashboardBody(
shinyjs::useShinyjs(),
textInput("name", label='New Menu Label', value = ""),
actionButton("update", "Update Label")
)
)
server <- function(input, output, session){
menulabel<-reactiveVal('Menu2')
output$menu2<-renderMenu({
menuItem(
menulabel(),
actionButton('dummy2', 'Dummy Button 2'),
checkboxInput('dummy4', 'Dummy 4')
)
})
observeEvent(input$update,{
menulabel(input$name) #instead of a reactive label and renderMenu(), use runjs() here?
shinyjs::disable('dummy1')
shinyjs::disable('dummy2')
shinyjs::disable('dummy3')
shinyjs::disable('dummy4')
})
}
shinyApp(ui, server)
What you can do is to take the first span
of your menu2
and update its html()
. Therefore you can replace the menulabel(input$name)
with
runjs(paste0("$('#menu2 span').first().html('", input$name, "')"))