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

oncomplete event with Shiny.onInputChange is executed only once #35

Closed drghirlanda closed 5 years ago

drghirlanda commented 5 years ago

Hi,

And thanks for rintrojs! I am trying to trigger a shiny event on completing the tour using Shiny.onInputChange. The code below sort of works, in that the event is triggered the FIRST time the tour is done, but not on subsequent tours. How can I solve this? Thanks!

library(shiny)
library(rintrojs)

ui <- shinyUI(
    fluidPage(
        introjsUI(),
        mainPanel(
            actionButton("button1","Button 1")
        )
    )
)

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

    steps <- data.frame(
        element = c("#button1"),
        intro = c("This is button 1")
    )

    observeEvent( input$button1, {
        message( "starting tour" )
        introjs(
            session,
            options = list(
                steps=steps
            ),
            events = list(
                oncomplete=I('Shiny.onInputChange("tour","done");')
            )
        )
    })

    observeEvent( input$tour, {
        message( "tour is done" )
    })

})

 # Run the application 
shinyApp(ui = ui, server = server)
carlganz commented 5 years ago

This is a Shiny reactivity issue. You are setting value "tour" to string "done" repeatedly, but since "tour" is already set to "done" after the first time it doesn't invalidate. Change "done" with Date.now() which will be different each time you press the button and you will get the result you want.

In instances like this, to force reactivity, instead of simply sending the value I want from Javascript to R, I send an object with the value I want and a timestamp so even if the value is the same the timestamp will be different and the object will invalidate.

drghirlanda commented 5 years ago

Thank you very much, I was not aware of this and your solution is very elegant!

This is a Shiny reactivity issue. You are setting value "tour" to string "done" repeatedly, but since "tour" is already set to "done" after the first time it doesn't invalidate. Change "done" with Date.now() which will be different each time you press the button and you will get the result you want.

In instances like this, to force reactivity, instead of simply sending the value I want from Javascript to R, I send an object with the value I want and a timestamp so even if the value is the same the timestamp will be different and the object will invalidate.

CyrusJoudieh commented 3 years ago

Hi All!

It might be late but good to know.

In this article in section From JavaScript to R -> Values vs. Events at https://shiny.rstudio.com/articles/communicating-with-js.html

they explain that a third parameter {priority: "event"} should be added if you want to let it trigger on every click.

Shiny.setInputValue("tour", "done", {priority: "event"});