PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, November 25, 2022

[FIXED] How do you have different server execution based on selected tabItem() in shiny?

 November 25, 2022     golem, module, r, shiny, shinyapps     No comments   

Issue

Background I am using {brochure} and {golem} to build a shiny app. I have one outer module grid that consists of inner modules subGrid2 which displays the same module UI on two tabs.

GOAL

  • have a module subGrid2 that can be used for repeating graph visualizations on multiple tabs.
  • in the REPREX --> fake graph generated from {shinipsum} to be displayed on the "Home" tab + "Portfolio" tab
  • use observeEvent to look at the slected tab and generate server response respectivley

Problem

The observeEvent reactive expr. fails to recognize when the corresponding tab is selected to generate the correct server response.

-using the reprex below replicates my issue-

TL/DR

  1. Why wont the observeEvent reactive generate the correct server response per the selected tab?

REPREX

uncomment observeEvent to see error

#22.2.22
library(brochure)

library(shiny)

library(shinipsum)

library(shinydashboard)

library(shinydashboardPlus)

mod_subGrid2_ui <- function(id) {
    ns <- NS(id)
    tagList(
        plotOutput(ns("plot"))
    )
}

mod_subGrid2_server <- function(id) {
    moduleServer(id, function(input, output, session) {
        ns <- session$ns

        output$plot <- renderPlot({
            shinipsum::random_ggplot()
        })
    })
}

#Setup dashboard

mod_Grid_ui <- function(id) {
    ns <- NS(id)

    shinydashboardPlus::dashboardPage(
        skin = "midnight",
        header = dashboardHeader(title = "test"),
        sidebar = dashboardSidebar(
            shinydashboard::sidebarMenu(
                # Setting id makes input$tabs give the tabName of currently-selected tab
                id = "tabs",
                menuItem("Home", tabName = "home", icon = icon("tachometer-alt")),
                menuItem("Portfolio", tabName = "portfolio", icon = icon("chart-line"), badgeLabel = "new",
                         badgeColor = "green")
            )
        ),

        body = shinydashboard::dashboardBody(
            # Enable shinyjs
            shinyjs::useShinyjs(),

            shinydashboard::tabItems(
                shinydashboard::tabItem("home",
                                        shiny::tagList(
                                            div(p("Content for 1st tab goes here -- GRID MODULE")),
                                            mod_subGrid2_ui(ns("subGrid2_ui_1"))
                                        )
                ),
                shinydashboard::tabItem("portfolio",
                                        shiny::tagList(
                                            div(p("Content for 2nd goes here -- GRID MODULE (2x)")),
                                            titlePanel(title = "The same module UI goes here"),

mod_subGrid2_ui(ns("subGrid2_ui_2"))
                                        )
                )
            )
        )
    )
}

mod_Grid_server <- function(id) {
    moduleServer(id, function(input, output, session) {
        ns <- session$ns
        mod_subGrid2_server("subGrid2_ui_1")
        mod_subGrid2_server("subGrid2_ui_2")

       ## uncomment to try
        # observeEvent(input$tabs,{
        #   if(input$tabs == "home"){
        #     # <subGrid> server fragment
        #     mod_subGrid2_server("subGrid2_ui_1")
        #   } else if(input$tabs == "portfolio"){
        #     mod_subGrid2_server("subGrid2_ui_1")
        #   }
        # }, ignoreNULL = TRUE, ignoreInit = TRUE)
    })
}

brochureApp(
    page(
        href = "/",
        ui = tagList(
            mod_Grid_ui("grid_1")
        ),
        server = function(input, output, session) {
            mod_Grid_server("grid_1")
        }
    ),
    wrapped = shiny::tagList
)

Solution

When using a module nested inside another module, you need to ns() the id of the nested UI function. So here, mod_subGrid2_ui(ns("subGrid2_ui_1")).

Here is a minimal reprex:

mod_subGrid2_ui <- function(id) {
  ns <- NS(id)
  tagList(
    plotOutput(ns("plot"))
  )
}

mod_subGrid2_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns

    output$plot <- renderPlot({
      shinipsum::random_ggplot()
    })
  })
}

mod_Grid_ui <- function(id) {
  ns <- NS(id)
  tagList(
    mod_subGrid2_ui(ns("subGrid2_ui_1"))
  )
}

mod_Grid_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    ns <- session$ns
    mod_subGrid2_server("subGrid2_ui_1")
  })
}

brochureApp(
  page(
    href = "/",
    ui = tagList(
      mod_Grid_ui("grid_1")
    ),
    server = function(input, output, session) {
      mod_Grid_server("grid_1")
    }
  )
)


Answered By - Colin FAY
Answer Checked By - David Goodson (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing