Home:ALL Converter>Shiny modules: switch tabs from within modules that have different namespaces

Shiny modules: switch tabs from within modules that have different namespaces

Ask Time:2021-11-04T04:48:48         Author:gulogulo

Json Formatter

I have a shiny app with multiple tabs, and I would like to have action buttons within the tabs that allow the user to switch tabs. I previously asked this question: R Shiny: Change tabs from within a module and got an answer that helped, but didn't completely solve my problem.

When I use the same id (tab.1) to call modtab1 and modtab2, it allows me to switch tabs, but it doesn't distinguish between the two input$userids; when I use different id's it distinguishes between the two input$userids but doesn't allow me to switch tabs.

library(shiny)
modtab1_ui <- function(id) {
  ns <- NS(id)
  tabPanel(title = 'Tab 1',
           value = NS(id, 'tab.1'),
           h4('This is the first tab'),
           actionButton(NS(id, 'nexttab'), 'Next Tab'),

           textInput(NS(id, 'userid'), 'User ID'),
           textOutput(outputId = NS(id, 'id'))
          ) # tabPanel
}

modtab1_server <- function(id) {
  moduleServer(id,
               function(input, output, session) {
                 observeEvent(input$nexttab, {
                   print(paste('switching to tab 2', input$userid))
                   updateTabsetPanel(session = session, inputId =  'tabs', 
                                     # selected = NS('tab2', 'tab.2')
                                     # selected = 'tab.2'
                                     selected = ns('tab.2')
                                    )
                 })
                 
                 output$id <- renderText(input$userid)
               })
}

modtab2_ui <- function(id) {
  ns <- NS(id)
  tabPanel(title = 'Tab 2',
           value = NS(id, 'tab.2'),

           h4('This is the second tab'),
           actionButton(NS(id, 'firsttab'), 'First Tab'),

           textInput(NS(id, 'userid'), 'User ID'),
           textOutput(outputId = NS(id, 'useridout'))
          ) # tabPanel
}

modtab2_server <- function(id) {
  moduleServer(id,
               function(input, output, session) {
                 observeEvent(input$firsttab, {
                   print(paste('switching to tab 1', input$userid))
                   updateTabsetPanel(session = session, inputId =  'tabs', 
                                     # selected = NS('tab1', 'tab.1')
                                     # selected = 'tab.1'
                                     selected = ns('tab.1')
                                     )
                 })
                 
                 output$id <- renderText(input$userid)
               })
}


ui <- fluidPage(
  tabsetPanel(
    'tabs',
             modtab1_ui('tab1'),
             modtab2_ui('tab2')
  )
)

server <- function(input, output, session) {
  modtab1_server('tab1')
  modtab2_server('tab2')
}

shinyApp(ui = ui, server = server)

Author:gulogulo,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/69831550/shiny-modules-switch-tabs-from-within-modules-that-have-different-namespaces
Limey :

Here's a MWE that, I think, gives you what you want.\nlibrary(shiny)\n\nmodtab1_ui <- function(id) {\n ns <- NS(id)\n tabPanel(\n title = 'Tab 1',\n value = ns('tab'),\n h4('This is the first tab'),\n actionButton(ns('nexttab'), 'Next Tab')\n ) # tabPanel\n}\n\nmodtab1_server <- function(id) {\n moduleServer(id,\n function(input, output, session) {\n retVal <- reactiveValues(count=0)\n \n observeEvent(input$nexttab, retVal$count <- retVal$count + 1)\n return(reactive(retVal$count))\n })\n}\n\nmodtab2_ui <- function(id) {\n ns <- NS(id)\n tabPanel(\n title = 'Tab 2',\n value = ns('tab'),\n h4('This is the second tab'),\n actionButton(ns('firsttab'), 'First Tab')\n ) # tabPanel\n}\n\nmodtab2_server <- function(id) {\n moduleServer(id,\n function(input, output, session) {\n retVal <- reactiveValues(count=0)\n \n observeEvent(input$firsttab, retVal$count <- retVal$count + 1)\n return(reactive(retVal$count))\n })\n}\n\nui <- fluidPage(\n tabsetPanel(\n id='tabs',\n modtab1_ui('tab1'),\n modtab2_ui('tab2')\n )\n)\n\nserver <- function(input, output, session) {\n \n tab1val <- modtab1_server('tab1')\n tab2val <- modtab2_server('tab2')\n \n observeEvent(tab1val(), {\n updateTabsetPanel(session, 'tabs', selected = 'tab2-tab')\n }) \n \n observeEvent(tab2val(), {\n updateTabsetPanel(session, 'tabs', selected = 'tab1-tab')\n })\n}\n\nshinyApp(ui = ui, server = server)\n\n\nNote the changes to your syntax, particularly regarding the use of ns and NS and the arguments passed to the functions.\nAlso, note the use of return values from the module server functions, and how they are accessed within the main server function.",
2021-11-04T10:19:17
yy