1

I want some animation on my conditionalpanels. I've found the solution provided here: Animation/transition for Shiny conditionalPanel

I really like the solution, but I have a problem. Check the following example:

library(shiny)
library(shinyjs)
library(shinydashboard)

ui <- dashboardPage(
  header = dashboardHeader(title = "test"),
  sidebar = dashboardSidebar(),
  shinydashboard::dashboardBody(
    fluidPage(
      useShinyjs(),
      
      tags$head(
        tags$link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.compat.min.css"),
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/animateCSS/1.2.2/jquery.animatecss.min.js")
      ),
      
      fluidRow(
        textOutput("test"),
        column(2, offset = 2, actionButton("prev_box", "Previous")),
        column(
          4,
          
          # conditionalPanel(condition = "output.phase_box_ui == 0",
          #                  uiOutput("box_move1")),
          # conditionalPanel(condition = "output.phase_box_ui > 0",
          #                  uiOutput("box_move2"))
          

          animatedConditionalPanel(
            condition = "output.phase_box_ui == 0",
            onShow = animateCSS("backInRight", duration = 1000),
            onHide = animateCSS("backOutLeft", duration = 1000),
            fadeIn = 0,
            fadeOut = 0,
            uiOutput("box_move1")
          ),
          animatedConditionalPanel(
            condition = "output.phase_box_ui == 1",
            onShow = animateCSS("backInRight", duration = 1000),
            onHide = animateCSS("backOutLeft", duration = 1000),
            fadeIn = 0,
            fadeOut = 0,
            uiOutput("box_move2")
          )
          
        ),
        column(2, actionButton("next_box", "Next"))
      )
    )
  )
)

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

  #### TEST BOX MOVING
  
  phase_box = reactiveVal(0)
  
  observeEvent(phase_box(),{
    if(phase_box() == 0){
      shinyjs::hide("prev_box")
    }else{
      shinyjs::show("prev_box")
    }
  })
  
  
  observeEvent(input$prev_box,{
    if(phase_box() > 0){
      val = phase_box() - 1
      phase_box(val)
    }
  })
  
  observeEvent(input$next_box,{
    if(phase_box() < 6){
      val = phase_box() + 1
      phase_box(val)
    }
  })
  
  output$test = renderText({
    phase_box()
  })
  
  output$phase_box_ui = reactive({return(phase_box())})
  outputOptions(output, "phase_box_ui", suspendWhenHidden = F)
  
  
  
  output$box_move1 = renderUI({
    shinydashboard::infoBox(title = "First box", value = 0, color = "red")

  })
  
  
  output$box_move2 = renderUI({
    shinydashboard::infoBox(title = "Second box", value = 1)
  })
  
}

shinyApp(ui, server)

enter image description here

The problem is at startup where both of them appear for a second and then disappear, but at startup the first box should be visible. How I can fix it?

EDIT:

Now the first problem is solved. However check the gif below:

enter image description here

When the second box arrives, it arrives below the first box and then suddenly it goes up. The effect can be nice if the transition wasn't immediately (it simply pops up in the correct place). Do you know if there is a solution? It's seems like, just for a moment (during the transition), they are displayed both and so the second box goes below the first.

Here is the behaviour adding 1s delay for the inShow transition of the second box. Maybe is more clear the problem.

enter image description here

EDIT2:

I have a bigger problem on nested conditionalpanels. When I put another conditionalpanel (a simple one) inside the animated, every time is triggered the inside condition, the animated run again the animation. Here's a reproducible example:

library(shiny)
library(shinyjs)
library(shinydashboard)

ui <- dashboardPage(
  header = dashboardHeader(title = "test"),
  sidebar = dashboardSidebar(),
  shinydashboard::dashboardBody(
    fluidPage(
      useShinyjs(),
      
      tags$head(
        tags$link(rel = "stylesheet", href = "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.compat.min.css"),
        tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/animateCSS/1.2.2/jquery.animatecss.min.js")
      ),
      
      fluidRow(
        textOutput("test"),
        column(2, offset = 2, actionButton("prev_box", "Previous")),
        column(
          4,
          
          animatedConditionalPanel(
            condition = "output.phase_box_ui == 0",
            onShow = animateCSS("backInRight", duration = 1000),
            onHide = animateCSS("backOutLeft", duration = 1000),
            fadeIn = 0,
            fadeOut = 0,
            uiOutput("box_move1")
          ),
          animatedConditionalPanel(
            condition = "output.phase_box_ui == 1",
            onShow = animateCSS("backInRight", duration = 1000),
            onHide = animateCSS("backOutLeft", duration = 1000),
            fadeIn = 0,
            fadeOut = 0,
            uiOutput("box_move2")
          )
          
        ),
        column(2, actionButton("next_box", "Next"))
      )
    )
  )
)

server <- function(input, output,session) {
  
  #### TEST BOX MOVING
  
  phase_box = reactiveVal(0)
  
  observeEvent(phase_box(),{
    if(phase_box() == 0){
      shinyjs::hide("prev_box")
    }else{
      shinyjs::show("prev_box")
    }
  })
  
  
  observeEvent(input$prev_box,{
    if(phase_box() > 0){
      val = phase_box() - 1
      phase_box(val)
    }
  })
  
  observeEvent(input$next_box,{
    if(phase_box() < 6){
      val = phase_box() + 1
      phase_box(val)
    }
  })
  
  output$test = renderText({
    phase_box()
  })
  
  output$phase_box_ui = reactive({return(phase_box())})
  outputOptions(output, "phase_box_ui", suspendWhenHidden = F)
  
  
  
  output$box_move1 = renderUI({
    fluidPage(
      shinydashboard::infoBox(title = "First box", value = 0, color = "red"),
      selectInput("step2", "Choose:", choices = c("one", "two")), br(),
      conditionalPanel(style = "display: none",
        condition = "input.step2 == 'two'",
        h4(strong("2. This is the second step"))
      )
    )
  })
  
  
  output$box_move2 = renderUI({
    shinydashboard::infoBox(title = "Second box", value = 1)
  })
  
}

shinyApp(ui, server)
Fabio DR
  • 89
  • 10
  • 2
    Try `style = "display: none"` in `animatedConditionalPanel`. – Stéphane Laurent Sep 09 '22 at 11:17
  • Wow thank you! Now it works flawlessly! So simple so effective. – Fabio DR Sep 09 '22 at 11:24
  • 2
    Please leave a comment or a "thumbs up" [here](https://github.com/rstudio/shiny/issues/3505) so eventually they'll make this the default behaviour. – ismirsehregal Sep 09 '22 at 11:47
  • I left a "thumbs up". I updated the original question with another problem. Can you help me? (I leave a comment since I don't know if you receive a notification for the edit). – Fabio DR Sep 09 '22 at 15:04
  • 1
    You might be better off creating a separate question. – ismirsehregal Sep 09 '22 at 21:21
  • Not sure to understand the question of your first edit. Do you need a delay? You can try `delay = 1000` in the `animateCSS` function. – Stéphane Laurent Sep 10 '22 at 08:49
  • With the delay the situation is worse, check the added gif. Basically when I click on the next button, the second box arrives one row below the first box, even if the first is already going. Probably on clicking both animation are triggered at almost same time, and so for a moment, there are kind of two fluidRow() (on for each box). Then, when the first box transition ends, the first row (where was the first box) disappears and the second box moves upward in the position of the first box (1st row) but immediately. Probably from the gif is not very clear the effect. – Fabio DR Sep 11 '22 at 15:03
  • However EDIT2 now it's more important. I opened another question: https://stackoverflow.com/questions/73680535/nested-animated-conditionalpanel – Fabio DR Sep 11 '22 at 15:35

0 Answers0