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

Conditional panels #49

Open lampoverde opened 4 years ago

lampoverde commented 4 years ago

Hello Everyone, I'm trying to build a guided tour among tabs which have conditional panels. While I can move through tabs, I cannot do that over conditional panels. I define the steps on the server side

DEFINITION OF STEPS

element <- c('#elem_A_tab1', '#elem_B_tab2_inCondPanel', '#elem_C_tab2_outOfCondPanel') intro <- paste0('text ', length(element)) tourData_rintro <- data.frame(element, intro)

START TOUR

introjs(session, options = list(steps = tourData_rintro), events = list(onbeforechange = readCallback("switchTabs")))

Steps involving hidden conditional panels are not properly shown when the panel is hidden. Is there any trick to open/close a conditional panel during the steps?

Many thanks for any insight Paolo

carlganz commented 4 years ago

Can you please provide a full reproducible example? In general, all elements of the intro need to be in the DOM when the intro starts. I can't remember off the top of my head but there may be a way to tell Shiny to render hidden elements to DOM even if they aren't shown.

lampoverde commented 4 years ago

Hello Carl, sorry for the late reply. I did some steps forward opening/closing conditionalpanels during rintrojs steps but there're some open issues and the solution I got until now is not elegant

I add a simple reprex

Many thanks for any help, Paolo

#

======================== RINTROJS WITH CONDITIONALPANELS

===================== #

library(shiny) library(shinyWidgets) library(rintrojs)

COMMENTS FOR ME

- open closing conditional panels during steps => ok however the

switchFilter doesn't change visually

- the first introjs step defined on #switchFilter doesn't work correctly

- find a way to put onchange events in the global data.frame

tourData_rintro_1

RINTROJS STEPS

element <- c('#switchFilter', '#n', '#input_text') intro <- c('Choose histogram or text','Here you can choose nr of observations','Here you can insert text') tourData_rintro_1 <- data.frame(element, intro)

n <- 200

ui <- bootstrapPage(

br(), br(), br(), introjsUI(),

START INTROJS

actionButton("btn_tour", "Tour"),

SWITCH BETWEEN TWO PANELS

shinyWidgets::materialSwitch(inputId = "switchFilter", label = "Filter", status = "danger", value = FALSE),

PANEL HISTOGRAM

conditionalPanel(condition = 'input.switchFilter', div(numericInput('n', 'Number of obs', n), plotOutput('plot'))),

PANEL TEXT

conditionalPanel(condition = '!input.switchFilter', textInput('input_text', 'write here'))

)

Define the server code

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

output$plot <- renderPlot({ hist(runif(input$n)) })

INTROJS TOUR

ONCHANGE BASED ON NR OF STEP ENABLE/DISABLE THE TWO CONDITIONAL PANELS

observeEvent(input$btn_tour, { rintrojs::introjs(session, options = list(steps = tourData_rintro_1) , events = list(onbeforechange = readCallback("switchTabs"), onchange = I(' (function(obj){

                                      if (obj._currentStep == 1){

Shiny.setInputValue("switchFilter", true, {priority: "event"}); }

                                      if (obj._currentStep == 2){

Shiny.setInputValue("switchFilter", false, {priority: "event"}); }

                                    })(this);
                      '))
)

})

}

Return a Shiny app object

shinyApp(ui = ui, server = server)

https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Mail priva di virus. www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

Il giorno lun 20 lug 2020 alle ore 22:58 Carl Ganz notifications@github.com ha scritto:

Can you please provide a full reproducible example? In general, all elements of the intro need to be in the DOM when the intro starts. I can't remember off the top of my head but there may be a way to tell Shiny to render hidden elements to DOM even if they aren't shown.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/carlganz/rintrojs/issues/49#issuecomment-661329662, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHVRLQAFAJM2RDRCOTV3F3R4SVXVANCNFSM4PCBGTMQ .

lampoverde commented 4 years ago

I solved two open points in my previous message

The remaining open point is putting onchange events inside tourData_rintro_1 is still unsolved.

Best, Paolo

#

======================== RINTROJS WITH CONDITIONALPANELS

===================== #

library(shiny) library(shinyWidgets) library(rintrojs)

COMMENTS

- open closing conditional panels during steps

=> for control animation put $("#switchFilter").prop("checked", true);

- the first introjs step defined on #switchFilter doesn't work correctly

=> PUT switchFilter INSIDE A DIV and focus on this one inside rintrojs

steps

- find a way to put onchange events in the global data.frame

tourData_rintro_1

UNSOLVED

RINTROJS STEPS

element <- c('#divswitch', '#n', '#numeri', '#input_text') intro <- c('Choose histogram or text','Here you can choose nr of observations', 'Here are all input numbers', 'Here you can insert text') tourData_rintro_1 <- data.frame(element, intro)

n <- 200

ui <- bootstrapPage(

br(), br(), br(), introjsUI(),

START INTROJS

actionButton("btn_tour", "Tour"),

SWITCH BETWEEN TWO PANELS

div(id = 'divswitch', shinyWidgets::materialSwitch(inputId = "switchFilter", label = "Filter", status = "danger", value = FALSE)),

PANEL HISTOGRAM

conditionalPanel(condition = 'input.switchFilter',

               div(id = 'numeri',
               numericInput('n', 'Number of obs', n),
               numericInput('m', 'FAKE Number of obs', n),
               ),

                   plotOutput('plot')),

PANEL TEXT

conditionalPanel(condition = '!input.switchFilter', textInput('input_text', 'write here'))

)

Define the server code

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

output$plot <- renderPlot({ hist(runif(input$n)) })

INTROJS TOUR

ONCHANGE BASED ON NR OF STEP ENABLE/DISABLE THE TWO CONDITIONAL PANELS

observeEvent(input$btn_tour, { rintrojs::introjs(session, options = list(steps = tourData_rintro_1) , events = list(onbeforechange = readCallback("switchTabs"), onchange = I(' (function(obj){

                                      if (obj._currentStep == 1){

Shiny.setInputValue("switchFilter", true, {priority: "event"});

$("#switchFilter").prop("checked", true); }

                                      if (obj._currentStep == 3){

Shiny.setInputValue("switchFilter", false, {priority: "event"});

$("#switchFilter").prop("checked", false); }

                                    })(this);
                      '))
)

})

}

Return a Shiny app object

shinyApp(ui = ui, server = server)

https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Mail priva di virus. www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

Il giorno sab 1 ago 2020 alle ore 10:08 Paolo Tenconi < paolo.tenconi@gmail.com> ha scritto:

Hello Carl, sorry for the late reply. I did some steps forward opening/closing conditionalpanels during rintrojs steps but there're some open issues and the solution I got until now is not elegant

I add a simple reprex

Many thanks for any help, Paolo

#

======================== RINTROJS WITH CONDITIONALPANELS

===================== #

library(shiny) library(shinyWidgets) library(rintrojs)

COMMENTS FOR ME

- open closing conditional panels during steps => ok however the

switchFilter doesn't change visually

- the first introjs step defined on #switchFilter doesn't work correctly

- find a way to put onchange events in the global data.frame

tourData_rintro_1

RINTROJS STEPS

element <- c('#switchFilter', '#n', '#input_text') intro <- c('Choose histogram or text','Here you can choose nr of observations','Here you can insert text') tourData_rintro_1 <- data.frame(element, intro)

n <- 200

ui <- bootstrapPage(

br(), br(), br(), introjsUI(),

START INTROJS

actionButton("btn_tour", "Tour"),

SWITCH BETWEEN TWO PANELS

shinyWidgets::materialSwitch(inputId = "switchFilter", label = "Filter", status = "danger", value = FALSE),

PANEL HISTOGRAM

conditionalPanel(condition = 'input.switchFilter', div(numericInput('n', 'Number of obs', n), plotOutput('plot'))),

PANEL TEXT

conditionalPanel(condition = '!input.switchFilter', textInput('input_text', 'write here'))

)

Define the server code

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

output$plot <- renderPlot({ hist(runif(input$n)) })

INTROJS TOUR

ONCHANGE BASED ON NR OF STEP ENABLE/DISABLE THE TWO CONDITIONAL PANELS

observeEvent(input$btn_tour, { rintrojs::introjs(session, options = list(steps = tourData_rintro_1) , events = list(onbeforechange = readCallback("switchTabs"), onchange = I(' (function(obj){

                                      if (obj._currentStep == 1){

Shiny.setInputValue("switchFilter", true, {priority: "event"}); }

                                      if (obj._currentStep == 2){

Shiny.setInputValue("switchFilter", false, {priority: "event"}); }

                                    })(this);
                      '))
)

})

}

Return a Shiny app object

shinyApp(ui = ui, server = server)

https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail Mail priva di virus. www.avast.com https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail <#m_-2765150087243535537_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

Il giorno lun 20 lug 2020 alle ore 22:58 Carl Ganz < notifications@github.com> ha scritto:

Can you please provide a full reproducible example? In general, all elements of the intro need to be in the DOM when the intro starts. I can't remember off the top of my head but there may be a way to tell Shiny to render hidden elements to DOM even if they aren't shown.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/carlganz/rintrojs/issues/49#issuecomment-661329662, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABHVRLQAFAJM2RDRCOTV3F3R4SVXVANCNFSM4PCBGTMQ .

ShinyFabio commented 3 years ago

Hi lampoverde, I tried your solution with a radiobutton but doesn't work. Here's my code:

library(shiny)
library(shinyWidgets)
library(rintrojs)

# COMMENTS

# - open closing conditional panels during steps
# => for control animation put $("#switchFilter").prop("checked", true);

# - the first introjs step defined on #switchFilter doesn't work correctly

# => PUT switchFilter INSIDE A DIV and focus on this one inside rintrojs
steps

# - find a way to put onchange events in the global data.frame
tourData_rintro_1
# UNSOLVED

# RINTROJS STEPS
element <- c('#divswitch', '#n', '#numeri', '#input_text', "#divradio", "#unoid", "#minestraid")
intro <- c('Choose histogram or text','Here you can choose nr of
observations', 'Here are all input numbers',
'Here you can insert text', "select radio here", "ti piace uno", "ti piace minestra")
tourData_rintro_1 <- data.frame(element, intro)

n <- 200

ui <- bootstrapPage(

  br(), br(), br(), introjsUI(),

  # START INTROJS
  actionButton("btn_tour", "Tour"),

  # SWITCH BETWEEN TWO PANELS
  div(id = 'divswitch', shinyWidgets::materialSwitch(inputId =
                                                       "switchFilter", label = "Filter", status = "danger", value = FALSE)),
  div(id = "divradio", radioButtons("radio1", "seleziona una cosa", choices = c("uno", "minestra"))),
  # PANEL HISTOGRAM
  conditionalPanel(condition = 'input.switchFilter',

                   div(id = 'numeri',
                       numericInput('n', 'Number of obs', n),
                       numericInput('m', 'FAKE Number of obs', n),
                   ),

                   plotOutput('plot')),
  conditionalPanel(condition = "input.radio1 == 'uno'", div(h4("questo dice che è uno"), id = "unoid")),
  conditionalPanel(condition = "input.radio1 == 'minestra'", div(h4("questo dice che è minestra"), id = "minestraid")),

  # PANEL TEXT
  conditionalPanel(condition = '!input.switchFilter',
                   textInput('input_text', 'write here'))

)

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

  output$plot <- renderPlot({
    hist(runif(input$n))
  })

  # INTROJS TOUR
  # ONCHANGE BASED ON NR OF STEP ENABLE/DISABLE THE TWO CONDITIONAL PANELS
  observeEvent(input$btn_tour, {
    rintrojs::introjs(session, options = list(steps = tourData_rintro_1)
                      ,
                      events = list(onbeforechange =
                                      readCallback("switchTabs"),
                                    onchange = I('
                                        (function(obj){

                                          if (obj._currentStep == 1){

Shiny.setInputValue("switchFilter", true, {priority: "event"});

$("#switchFilter").prop("checked", true);
                                          }

                                          if (obj._currentStep == 3){

Shiny.setInputValue("switchFilter", false, {priority: "event"});

$("#switchFilter").prop("checked", false);
                                          }
                                          if (obj._currentStep == 5){

Shiny.setInputValue("radio1", "uno", {priority: "event"});

$("#radio1").prop("checked", "uno");
                                          }

                                          if (obj._currentStep == 6){

Shiny.setInputValue("radio1", "minestra", {priority: "event"});

$("#radio1").prop("checked", "minestra");
                                          }

                                        })(this);
                          '))
    )

  })

}

# Return a Shiny app object
shinyApp(ui = ui, server = server)