rintrojs icon indicating copy to clipboard operation
rintrojs copied to clipboard

Conditional panels

Open lampoverde opened this issue 4 years ago • 4 comments

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

lampoverde avatar Jul 20 '20 08:07 lampoverde

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.

carlganz avatar Jul 20 '20 20:07 carlganz

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 [email protected] 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 avatar Aug 01 '20 08:08 lampoverde

I solved two open points in my previous message

  • materialSwitch rintrojs selection (by putting #switchFilter inside a div)
  • materialSwitch animation during steps by using $("#switchFilter").prop() method

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 < [email protected]> 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 < [email protected]> 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 avatar Aug 01 '20 11:08 lampoverde

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)

ShinyFabio avatar Jun 30 '21 11:06 ShinyFabio