Search code examples
rshinycarouselnavbarslickr

Shiny Slick R carousel with internal links to tab panels


I would like to create a shiny navbarPage dashboard that has a slickR carousel of images on the landing page. Each image should have an action button superimposed that links to a different tabPanel. It should basically look like this: Screenshot of toy app Here is reproducible toy example that doesn't do the job:`

library(shiny)
library(slickR)
# ui
ui <- navbarPage(title = "", id = "pageid",
                 tabsetPanel(id="tabs",
                             tab1 <- tabPanel(title="Tab 1", value="tab1",
                                              fluidRow(
                                                slickROutput("slickr1"),
                                                h1("Title", style =
                                                     "position: relative;
                                                      margin-top:-43%;
                                                      color:#4BACC6;
                                                      font-size:30px;
                                                      text-align: center"),
                                                div(actionButton("action1", "Action",
                                                                 style="position: relative;
                                                                  margin-top: 15%;
                                                                  color:#FFFEFB;
                                                                  background-color:#4BACC6;
                                                                  border-color:#4BACC6;"), 
                                                    align="center"),
                                                                            )),
                             tab2 <- tabPanel(title="Tab 2", value="tab2"),
                             tab3 <- tabPanel(title="Tab 3", value="tab3")
                 )
)

# server
server <- function(input, output, session) {
  output$slickr1 <- renderSlickR({
    slick1 <- slick_list(slick_div(
      nba_player_logo$uri[1:3],
      type = "img", links = NULL)
    )
    slickR(slick1) +
      settings(dots = TRUE,
               autoplay = TRUE)
  })
  observeEvent(input$action1, {
    updateTabsetPanel(session, "tabs",
                      selected = "tab2")
  })
}

` This code superimposes the same action button and title on all three images on the carousel and I can't get slickR to run through both images and action buttons.

I have tried to create a second slick_div within the slick_list that runs through three different action buttons, like this: `

# server
server <- function(input, output, session) {
  buttons <- list(actionButton("action1", "Action1"),
                 actionButton("action2", "Action2"),
                 actionButton("action3", "Action3"))                         
  output$slickr1 <- renderSlickR({
    slick1 <- slick_list(slick_div(
      nba_player_logo$uri[1:3],
      type = "img", links = NULL),
    slick_div(
      buttons,
      css = htmltools::css(display = "inline"),
      links = NULL)
  )
    slickR(slick1) +
      settings(dots = TRUE,
               autoplay = TRUE)
  })
  observeEvent(input$action1, {
    updateTabsetPanel(session, "tabs",
                      selected = "tab2")
  })
}

` But it somehow just ends up stacking all the images on top each other for slide 1 and all action buttons next to each other on slide 2, rather than running through them one by one with one image and one action button on each slide.

Alternatively, I would also be open to having the entire image link to a different tab and I thought about using the "links" option in slick_div (set to NULL in the toy example above), but I'm struggling to determine a url for each of tabs that I could assign to "links".

I'm new to shiny and would really appreciate your help!


Solution

  • I'm not sure to understand. Is it what you want?

    library(shiny)
    library(slickR)
    
    css <- "
    .slidetitle {
      position: relative;
      color: #4BACC6;
      font-size: 30px;
      text-align: center;
    }
    .slidebutton {
      position: relative;
      margin-top: -15%;
      color: #FFFEFB;
      background-color: #4BACC6;
      border-color: #4BACC6;
    }
    "
    
    
    # ui
    ui <- navbarPage(
      title = "SlickR with buttons", 
      id = "tabs",
      header = tags$head(tags$style(HTML(css))),
      tabPanel(
        title= "Tab 1", value = "tab1",
        fluidRow(
          slickR(slick_list(
            tags$div(
              tags$h1("Title 1", class = "slidetitle"),
              tags$img(
                src = "https://cdn.pixabay.com/photo/2018/07/31/22/08/lion-3576045__340.jpg",
                height = 500
              ),
              actionButton(
                "action1", "Action 1", class = "slidebutton"
              ),
              align = "center"
            ),
            tags$div(
              tags$h1("Title 2", class = "slidetitle"),
              tags$img(
                src = "https://cdn.pixabay.com/photo/2012/02/27/15/35/lion-17335__340.jpg",
                height = 500
              ),
              actionButton(
                "action2", "Action 2", class = "slidebutton"
              ),
              align = "center"
            ),
            tags$div(
              tags$h1("Title 3", class = "slidetitle"),
              tags$img(
                src = "https://www.aprenderjuntos.cl/wp-content/uploads/2020/08/LEON-SERIO-.jpg",
                height = 500
              ),
              actionButton(
                "action3", "Action 3", class = "slidebutton"
              ),
              align = "center"
            )
          )) + settings(autoplay = TRUE, dots = TRUE)
        )
      ),
      tabPanel(
        title = "Tab 2", value = "tab2",
        tags$h1("TAB 2")
      ),
      tabPanel(
        title = "Tab 3", value = "tab3",
        tags$h1("TAB3")
      )
    )
    
    # server
    server <- function(input, output, session) {
      observeEvent(input$action1, {
        updateNavbarPage(session, "tabs", selected = "tab2")
      })
    }
    
    shinyApp(ui, server)
    

    To have the title on top of the image, use this CSS:

    .slidecontainer {
      position: relative;
    }
    .slidetitle {
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      color: #4BACC6;
      font-size: 30px;
    }
    .slidebutton {
      position: relative;
      margin-top: -15%;
      color: #FFFEFB;
      background-color: #4BACC6;
      border-color: #4BACC6;
    }
    

    and add the class slidecontainer to the div elements:

          slickR(slick_list(
            tags$div(
              class = "slidecontainer",
              tags$h1("Title 1", class = "slidetitle"),
              tags$img(
                src = "https://cdn.pixabay.com/photo/2018/07/31/22/08/lion-3576045__340.jpg",
                height = 500
              ),
              actionButton(
                "action1", "Action 1", class = "slidebutton"
              ),
              align = "center"
            ),
            ......