JohnCoene / cicerone

🏛️ Give tours of your Shiny apps
https://cicerone.john-coene.com
Other
187 stars 7 forks source link

Working with modules (2) #29

Closed gueyenono closed 3 years ago

gueyenono commented 3 years ago

This question is an extension of the question asked in #27 about using {cicerone} in the context of modules.

cicerone_with_modules

Each highlighted box is a module and I would like my guided tour to highlight Box 1, then highlight Box 2. In Issue #27, the solution was to create the guide inside the module. In my case, this will not cut it. Is there any way to achieve my desired result?

Thank you.

Reproducible code:

library(shiny)
library(bs4Dash)
library(cicerone)

# Module for box 1 ----

mod_box1_ui <- function(id){
  ns <- NS(id)
  box(
    id = ns("box1"),
    title = "Box 1",
    numericInput(ns("num"), label = "Enter a number", value = 5, min = 0, max = 10)
  )
}

mod_box1_server <- function(input, output, session){
  ns <- session$ns
}

# Module for box 2 ----

mod_box2_ui <- function(id){
  ns <- NS(id)
  box(
    id = ns("box2"),
    title = "Box 2",
    sliderInput(ns("slide"), label = "Choose a number", value = 5, min = 0, max = 10)
  )
}

mod_box2_server <- function(input, output, session){
  ns <- session$ns
}

# Cicerone guide ----

guide <- Cicerone$
  new()$
  step(
    el = "box1",
    title = "Step 1",
    description = "This is box 1."
  )$
  step(
    el = "box2",
    title = "Step 2",
    description = "This is box 2."
  )

# Main app ----

ui <-   dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    fluidRow(
      mod_box1_ui("box1"),
      mod_box2_ui("box2")
    )
  ),
  dashboardControlbar(),
  dashboardFooter()
)

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

  guide$init()$start()
  callModule(mod_box1_server, "box1")
  callModule(mod_box2_server, "box2")

}

shinyApp(ui = ui, server = server)
JohnCoene commented 3 years ago

You could do something as shown below.

  1. Create the guide
  2. Add steps in individual modules using ns
  3. Initialise the guide after calling the modules
library(shiny)
library(bs4Dash)
library(cicerone)

# Cicerone guide ----

guide <- Cicerone$new()

# Module for box 1 ----

mod_box1_ui <- function(id){
  ns <- NS(id)
  box(
    id = ns("box1"),
    title = "Box 1",
    numericInput(ns("num"), label = "Enter a number", value = 5, min = 0, max = 10)
  )
}

mod_box1_server <- function(input, output, session){
  ns <- session$ns
  guide$
    step(
      el = ns("box1"), # use namespace
      title = "Step 1",
      description = "This is box 1."
    )
}

# Module for box 2 ----

mod_box2_ui <- function(id){
  ns <- NS(id)
  box(
    id = ns("box2"),
    title = "Box 2",
    sliderInput(ns("slide"), label = "Choose a number", value = 5, min = 0, max = 10)
  )
}

mod_box2_server <- function(input, output, session){
  ns <- session$ns
  guide$
    step(
      el = ns("box2"),
      title = "Step 2",
      description = "This is box 2."
    )
}

# Main app ----

ui <-   dashboardPage(
  dashboardHeader(title = "Basic dashboard"),
  dashboardSidebar(),
  dashboardBody(
    use_cicerone(),
    fluidRow(
      mod_box1_ui("box1"),
      mod_box2_ui("box2")
    )
  ),
  dashboardControlbar(),
  dashboardFooter()
)

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

  callModule(mod_box1_server, "box1")
  callModule(mod_box2_server, "box2")

  # launch after module called
  guide$init()$start()
}

shinyApp(ui = ui, server = server)
gueyenono commented 3 years ago

@JohnCoene

Oh okay, so the guide object is part of the session variable?"

Thank you very much for everything.

PS: I already preordered my Javascript for R copy :)