Dynamically changing the height of a div that is populated via a script causes issues in Shiny

25 views
Skip to first unread message

Bryan Britten

unread,
Dec 21, 2015, 10:04:40 AM12/21/15
to Shiny - Web Framework for R
I've got an app that is embedding a timeline via the htmlOutput function in Shiny. The code is a bit long-winded, but can be seen in full here and a (sort of) working demo can be seen here. Essentially, though, the problem can be broken down as such:

The problem:
The height of the timeline is currently hard coded to maximize the view on my work computer. However, on smaller screens, a height of 1000px is too big, so I want to change it dynamically such that it's 100% of the height of the screen minus the height of the menu bar. The code that does this (using JQuery) is:

$("#timeline-embed").css("height", ($(window).outerHeight() - $("#menu").outerHeight()) + "px");

However, when I try to add this code to $(document).ready(), $(window).ready(), or $(window).load(), it fires too quickly as Shiny has not populated the timeline yet and it re-renders everything, thus resetting the height value that is hard coded. However, this code does work when used with window.onresize.


The question:
 How do I properly get JQuery to wait to run this piece of code until after Shiny has fully rendered the timeline? It's worth noting that outside of the Shiny app, this code works fine if it's appended to $(window).load().


The (barebones) app:
# ui.R

shinyUI(fluidPage(
  fluidRow(
    id = "menu",
    column(4, actionButton(...), actionButton(...)),
    column(4, offset = 4, actionButton(...), ...)
  ),
  fluidRow(
    class = "timeline",
    column(12,
      div(class = "outer", htmlOutput("timeline"))
  )
))

# server.R

library(shiny)
library(magrittr)
source("timelinejs.R")

shinyServer(function(input, output, session) {
  tl <- new_timeline() %>% add_event(headline = "Example Event", text = "This is just a sample slide and should be deleted", start_date = "2015")
 
  output$timeline <- renderUI({
    tl %>% save(destfile = NA) %>% HTML() # this forces the timeline to spit out the HTML of the timeline so it can be embedded
  })
})

# timelinejs.R

.generate_html <- function(timeline) {
  timeline_json <- code_to_generate_json() # pseudo-code
 
  html_string <- paste('<!DOCTYPE html><html><head>...</head><body><div id = "timeline-embed" style = "width: 100%; height: 1000px;"></div><script type = "text/javascript">var timeline_json =',
                                timeline_json,
                                '; window.timeline = new TL.Timeline("timeline_embed", timeline_json);</script></body></html>')

  timeline$html_string <- html_string
  return(timeline)
}

save <- function(timeline, destfile) {
   timeline <- .generate_html(timeline)
   if (is.na(destfile)) {
     return(timeline$html_string)
   } else {
     write(self$html_string, file = destfile)
  }
}


Reply all
Reply to author
Forward
0 new messages