Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flexdashboard doesn't work with Shiny URL state

I am trying to combine flexdashboard with Shiny state bookmarking. When used alone (example from the docs) Shiny app works fine, but when put in flexdasboard, url is not updated:

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
    runtime: shiny
---

```{r setup, include=FALSE}
library(flexdashboard)
```

Column {data-width=650}
-----------------------------------------------------------------------

### Chart A

```{r}

shinyApp(
  ui=function(req) {
    fluidPage(
      textInput("txt", "Text"),
      checkboxInput("chk", "Checkbox")
    )
  },
  server=function(input, output, session) {
    observe({
      # Trigger this observer every time an input changes
      reactiveValuesToList(input)
      session$doBookmark()
    })
    onBookmarked(function(url) {
      updateQueryString(url)
    })
  },
  enableBookmarking = "url"
)

```

Is this even possible? Compared to standalone execution:

shinyApp(
  ui=function(req) {
    fluidPage(
      textInput("txt", "Text"),
      checkboxInput("chk", "Checkbox")
    )
  },
  server=function(input, output, session) {
    observe({
      # Trigger this observer every time an input changes
      reactiveValuesToList(input)
      session$doBookmark()
    })
    onBookmarked(function(url) {
      updateQueryString(url)
    })
  },
  enableBookmarking = "url"
)

it looks like onBookmarked (and similar events like onBookmark, onRestore and onRestored) are never triggered.

like image 264
user8954262 Avatar asked Nov 16 '17 21:11

user8954262


1 Answers

Bookmarking isn't supported in Shiny apps embedded in R Markdown documents.

See discussion here: https://github.com/rstudio/shiny/pull/1209#issuecomment-227207713

Sounds like it's technically possible, but tricky to do. For example, what happens if there are multiple apps embedded in the document? Also, apps are embedded as iframes, so there would have to be some wiring up to be done to allow these apps to access/modify their parent window's URL.


However, bookmarking does work with embedded Shiny components (rather than full applications).

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
runtime: shiny
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
enableBookmarking("url")
```

```{r, include=FALSE}
observe({
  reactiveValuesToList(input)
  session$doBookmark()
})

onBookmarked(function(url) {
  updateQueryString(url)
})

output$content <- renderUI({
  tagList(
    textInput("txt", "Text"),
    checkboxInput("chk", "Checkbox")
  )
})
```

Column {data-width=650}
-----------------------------------------------------------------------

### Chart A

```{r}
fluidPage(
  uiOutput("content"),
  selectInput("sel", label = "Select", choices = c(10, 20, 30), selected = 10)
)
```

You can also use Prerendered Shiny Documents, although bookmarking would not work 100% the same since the UI is pre-rendered. Any static UI would have to be manually restored with bookmarking callbacks, but dynamic UI would be restored just fine.

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
runtime: shiny_prerendered
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
enableBookmarking("url")
```

```{r, context="server"}
observe({
  reactiveValuesToList(input)
  session$doBookmark()
})

onBookmarked(function(url) {
  updateQueryString(url)
})

# Static inputs are pre-rendered, and must be manually restored 
onRestored(function(state) {
  updateSelectInput(session, "sel", selected = state$input$sel)
})

# Dynamic inputs will be restored with no extra effort
output$content <- renderUI({
  tagList(
    textInput("txt", "Text"),
    checkboxInput("chk", "Checkbox")
  )
})
```

Column {data-width=650}
-----------------------------------------------------------------------

### Chart A

```{r}
fluidPage(
  uiOutput("content"),
  selectInput("sel", label = "Select", choices = c(10, 20, 30), selected = 10)
)
```
like image 183
greg L Avatar answered Oct 28 '22 03:10

greg L