Search code examples
rshinyslickr

R shiny: slickROutput disappears when switching tabpanel()


I am making a Shiny app with tabPanels embedded in a navbarPage. In each tabPanel, I generate a serie of image. When switching from one panel to the other one, the image loaded in one of them disappear.

I have to "refresh" manually the page to see it again. The problem seems similar than the one posted here but I cannot really subset my tabPanels, even though I gave $id and value to them.

Here is a reproducible example:

library(shiny)
library(shinythemes)
library(slickR)

## ui ----

# Image list
imgs <- list(
    stackoverflow =
        "https://upload.wikimedia.org/wikipedia/fr/9/95/Stack_Overflow_website_logo.png",
    stackexchange =
        "https://upload.wikimedia.org/wikipedia/commons/6/6f/Stack_Exchange_Logo.png"
)

ui <- navbarPage(title = div(
    HTML('<span style="font-size:180%;color:white;font-weight:bold;"> Navbarpage</span></a>'),
    tags$style(style = 'position:absolute; right:42px;'),
    tags$style(HTML("#panel1{font-size: 25px}")),
    tags$style(HTML("#panel2{font-size: 25px}")),
    tags$style(HTML("#panel_about{font-size: 25px}"))
),
theme = shinytheme("flatly"),
windowTitle = "Navbarpage",
id = "navbar",

## First tabpanel ----
tabPanel(h1(id = "panel1", "Panel 1"), value = 1, fluid = TRUE,
         fluidRow(column(4,
                         selectInput("img_list", "Image list",
                                     choices = imgs,
                                     selected = imgs[1])),
                  column(8,
                         slickROutput("plot_panel1"))),
),
tabPanel(h1(id = "panel2", "Panel 2"), value = 2, fluid = TRUE,
         fluidRow(column(4,
                         selectInput("img_list", "Image list",
                                     choices = imgs,
                                     selected = imgs[1])),
                  column(8,
                         slickROutput("plot_panel2"))),
)
) # closes navbarpage

## server ----
server <- function(input, output, session){

    observe({
        output$plot_panel1 <- renderSlickR({
            slick1 <- slick_list(slick_div(
                input$img_list,
                css = htmltools::css(width = "100%", margin.left = "auto",
                                     margin.right = "auto"),
                type = "img", links = NULL))
            slickR(slick1)
        })
    })
    
    observe({
        output$plot_panel2 <- renderSlickR({
            slick2 <- slick_list(slick_div(
                input$img_list,
                css = htmltools::css(width = "100%", margin.left = "auto",
                                     margin.right = "auto"),
                type = "img", links = NULL))
            slickR(slick2)
        })
    })
}

shinyApp(ui, server)

And what it produces: enter image description here


Solution

  • When there are multiple slickR objects to be rendered, you need to use a unique slideId for each. Furthermore you should not wrap render* functions in observe and use the same id for two selectInputs.

    Please check the following:

    library(shiny)
    library(shinythemes)
    library(slickR)
    
    ## ui ----
    
    # Image list
    imgs <- list(
      stackoverflow =
        "https://upload.wikimedia.org/wikipedia/fr/9/95/Stack_Overflow_website_logo.png",
      stackexchange =
        "https://upload.wikimedia.org/wikipedia/commons/6/6f/Stack_Exchange_Logo.png"
    )
    
    ui <- navbarPage(title = div(
      HTML('<span style="font-size:180%;color:white;font-weight:bold;"> Navbarpage</span></a>'),
      tags$style(style = 'position:absolute; right:42px;'),
      tags$style(HTML("#panel1{font-size: 25px}")),
      tags$style(HTML("#panel2{font-size: 25px}")),
      tags$style(HTML("#panel_about{font-size: 25px}"))
    ),
    theme = shinytheme("flatly"),
    windowTitle = "Navbarpage",
    id = "navbar",
    
    ## First tabpanel ----
    tabPanel(h1(id = "panel1", "Panel 1"), value = 1, fluid = TRUE,
             fluidRow(column(4,
                             selectInput("img_list1", "Image list",
                                         choices = imgs,
                                         selected = imgs[1])),
                      column(8,
                             slickROutput("plot_panel1"))),
    ),
    tabPanel(h1(id = "panel2", "Panel 2"), value = 2, fluid = TRUE,
             fluidRow(column(4,
                             selectInput("img_list2", "Image list",
                                         choices = imgs,
                                         selected = imgs[1])),
                      column(8,
                             slickROutput("plot_panel2"))),
    )
    ) # closes navbarpage
    
    ## server ----
    server <- function(input, output, session){
      
        output$plot_panel1 <- renderSlickR({
          slick1 <- slick_list(slick_div(
            input$img_list1,
            css = htmltools::css(width = "100%", margin.left = "auto",
                                 margin.right = "auto"),
            type = "img", links = NULL))
          slickR(slick1, slideId = "slide1")
        })
      
        output$plot_panel2 <- renderSlickR({
          slick2 <- slick_list(slick_div(
            input$img_list2,
            css = htmltools::css(width = "100%", margin.left = "auto",
                                 margin.right = "auto"),
            type = "img", links = NULL))
          slickR(slick2, slideId = "slide2")
        })
    }
    
    shinyApp(ui, server)