Closed shahreyar-abeer closed 3 years ago
Using ns()
in modules just append the id of the module to the id of the input/output. Therefore, if you want to use cicerone
on single elements (e.g plots or table) that are created in a module, you can specify the full id. For example:
library(shiny)
library(cicerone)
guide <- Cicerone$
new()$
step(
"first_module-plot_test",
'Hello',
'This is a plot'
)
mod_1_ui <- function(id) {
ns <- NS(id)
tagList(
plotOutput(ns("plot_test"))
)
}
mod_1_server <- function(input, output, session) {
output$plot_test <- renderPlot({
plot(mtcars)
})
}
ui <- fluidPage(
use_cicerone(),
mod_1_ui("first_module")
)
server <- function(input, output, session) {
guide$init()$start()
callModule(mod_1_server, "first_module")
}
shinyApp(ui, server)
In one of my app, I had one module per tabPanel
and I only wanted to highlight the name of the tabPanel
(to say "this panel describes.... and this panel describes..., etc). One option for this is to give a value to each tabPanel
and then to use data-value
in the guide. For example:
library(shiny)
library(cicerone)
guide <- Cicerone$
new()$
step(
"[data-value='first_panel']",
'Hello',
'This is a panel',
is_id = FALSE
)
mod_1_ui <- function(id) {
ns <- NS(id)
tabPanel(
"First panel",
value = "first_panel",
plotOutput(ns("plot_test"))
)
}
mod_1_server <- function(input, output, session) {
output$plot_test <- renderPlot({
plot(mtcars)
})
}
ui <- navbarPage(
use_cicerone(),
mod_1_ui("first_module")
)
server <- function(input, output, session) {
guide$init()$start()
callModule(mod_1_server, "first_module")
}
shinyApp(ui, server)
These are the solutions I use but I don't know if there's a cleaner way to do this. Maybe it would useful to include an example for this in the documentation?
It's not ideal, I will re-work cicerone eventually.
When using modules it's easier to define the guide (Cicerone$new()
) within the module then use the namespace (ns
).
Cicerone$
new()$
step(
ns("id"),
"Title",
"Description"
)
@etiennebacher Thanks! I am doing it just like you said at the moment. But as @JohnCoene just mentioned. It's not ideal. Waiting for some workarounds from @JohnCoene
Oh and by 'within the module', do you mean inside the ui function? @JohnCoene
@shahreyar-abeer
You can use it like this.
library(shiny)
library(cicerone)
mod_ui <- function(id){
ns <- NS(id)
tagList(
actionButton(
ns("start"),
"Start tour"
),
textInput(
ns("text"),
"Label"
)
)
}
mod_server <- function(input, output, session){
ns <- session$ns
guide <- Cicerone$
new()$
step(
ns("text"),
"Text Input",
"This is a text input"
)
observeEvent(input$start, {
guide$init()$start()
})
}
ui <- fluidPage(
use_cicerone(),
mod_ui("module")
)
server <- function(input, output, session){
callModule(mod_server, "module")
}
shiny::shinyApp(ui, server)
Thanks!
It's not ideal, I will re-work cicerone eventually.
When using modules it's easier to define the guide (
Cicerone$new()
) within the module then use the namespace (ns
).Cicerone$ new()$ step( ns("id"), "Title", "Description" )
@JohnCoene
Does that mean that it is currently impossible to use {cicerone}
in the following context until the planned re-work of the package?
Each of highlighted boxes is a module and I would like my guided tour to highlight Box 1, then highlight Box 2. It may be currently impossible to achieve this since guides need to be defined "inside" modules.
My 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)
It's not ideal, I will re-work cicerone eventually. When using modules it's easier to define the guide (
Cicerone$new()
) within the module then use the namespace (ns
).Cicerone$ new()$ step( ns("id"), "Title", "Description" )
@JohnCoene
Does that mean that it is currently impossible to use
{cicerone}
in the following context until the planned re-work of the package?Each of highlighted boxes is a module and I would like my guided tour to highlight Box 1, then highlight Box 2. It may be currently impossible to achieve this since guides need to be defined "inside" modules.
My 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)
This question was answered by @JohnCoene in #29
How will it be integrated in an app with modules?