carlganz / rintrojs

Wrapper for the Intro.js library
http://rintrojs.carlganz.com/
GNU Affero General Public License v3.0
133 stars 11 forks source link

Are multiple intros per app possible? #23

Closed sy2816 closed 5 years ago

sy2816 commented 7 years ago

I just came across this app and was easily able to write an intro for my a small app of mine. However, I want to use it for a much larger one (it uses Shiny Dashboard, so there are several tabs and such), but I would prefer it I could essentially have an intro for each page/tab rather than a single intro for the entire app.

I checked around, and I couldn't find anything on it, did I miss something or is it not possible?

carlganz commented 7 years ago

Hello,

Short answer is yes. Long answer is you have to use server side intros. So for example:

library(shiny)
library(rintrojs)

ui <- fluidPage(
  rintrojs::introjsUI(),
  tabsetPanel(id = "tabs",
              tabPanel("one",h1("One", id = "one")),
              tabPanel("two",h1("Two", id = "two"))),
  actionButton("intro", "Start Intro")
)

server <- function(input,output,session) {
  observeEvent(input$intro, {
    if (input$tabs == "one") {
      rintrojs::introjs(session, options = list(
        steps = data.frame(element = c(NA, "#one"),
                   intro = c("This first step is the same regardless of the tab, but the second step is different",
                             "This is the first tab"))
      ))
    } else if (input$tabs == "two") {
      rintrojs::introjs(session, options = list(
        steps = data.frame(element = c(NA, "#two"),
                           intro = c("This first step is the same regardless of the tab, but the second step is different",
                                     "This is the second tab"))
      ))
    }
  })
}

shinyApp(ui,server)

Let me know if that helps

Sovik-Gupta commented 6 years ago

Just wanted to know if in the above example we have the tabsetPanel inside a DashboardBody, then how can we refer the same tabset in server .

carlganz commented 6 years ago

Please provide minimal reproducible example of problem you are having. There shouldn't be any issues with tabsetPanel inside dashboard body.

RoyMudie commented 5 years ago

Any chance of adding in the introjs support to use target element that let you specify a CSS class?

https://introjs.com/docs/intro/api/

ShinyFabio commented 3 years ago

Is it possible to have multiple independent instances? I mean like for every tabpanel I have a button that activate an infobox.

carlganz commented 3 years ago

It's possible there have been updates to the underlying the JS library that make this possible so I would recommend looking there first, but based on my memory you will not be able to create parallel static intro.js instances, instead you'll have to dynamically generate the intro in the server based on the value of the selected tabpanel

ShinyFabio commented 3 years ago

I managed to use multiple buttons for multiple instances. I modified a bit your example in order to find a solution to my problem. Here my code.

library(shiny)
library(rintrojs)

ui <- fluidPage(
  rintrojs::introjsUI(),
  tabsetPanel(id = "tabs",
              tabPanel("one",h1("One", id = "one"), actionButton("intro", "Start Intro")),
              tabPanel("two",
                       h1("Two", id = "two"),
                       actionButton("intro2", "Start Intro2"),
                       plotOutput("plotto"),
                       radioButtons(inputId = "radio", "apri questo", choices = c("before", "after")),
                       conditionalPanel(condition = "input.radio == 'before'",
                                        actionButton("eccolo", "button")
                       ),
                       conditionalPanel(condition = "input.radio == 'after'",
                                        sliderInput("slider1", label = h3("Slider"), min = 0, 
                                                    max = 100, value = 50)
                       )
              )),
)

server <- function(input,output,session) {
  observeEvent(input$intro, {
    if (input$tabs == "one") {
      rintrojs::introjs(session, options = list(
        steps = data.frame(element = c(NA, "#one"),
                           intro = c("This first step is the same regardless of the tab, but the second step is different",
                                     "This is the first tab"))
      ))
    } 
  })

  output$plotto = renderPlot(plot(x=1,y=5))
  observeEvent(input$intro2, {
    if (input$tabs == "two") {
      rintrojs::introjs(session, options = list("nextLabel"="Prossimo",
                                                "prevLabel"="Precedente",
                                                "skipLabel"="Chiudi",
                                                "doneLabel" = "Fatto",
                                                steps = data.frame(element = c(NA, "#two", "#plotto", "#radio", "#eccolo", "#slider1"),
                                                                   intro = c("This first step is the same regardless of the tab, but the second step is different",
                                                                             "This is the second tab", "A beautiful plot", "A radio button", "This is a button", "This is a slider")
                                                )
      ))
    }

  })
}

shinyApp(ui,server)

The only problem is with the conditionalPanel. If input.radio == 'before'" it shows correctly the button help but not the slider help. If I instead select "after", it doesn't show correctly neither the button help nor the slider help. Do you know how I can solve?