javascriptrshinydt

R shiny build links between apps


I have two shiny apps and I would like to link one to another. One has a datatable with some values that I would like to link to another app, where I can select this value from the selectInput option.

To sum it up I have one app that looks like this (taken from here):

library(shiny)
library(DT)

server <- function(input, output) {
  output$iris_type <- DT::renderDataTable({
    datatable(data.frame(Species=paste0("<a href='#filtered_data'>", unique(iris$Species), "</a>")),
              escape = FALSE,
              callback = JS(
                'table.on("click.dt", "tr", function() {
                tabs = $(".tabbable .nav.nav-tabs li a");
                $(tabs[1]).click();})'))
  })

  output$filtered_data <- DT::renderDataTable({
    selected <- input$iris_type_rows_selected
    if(is.null(selected)){
      datatable(iris)
    } else {
      datatable(iris[iris$Species %in% unique(iris$Species)[selected], ])
    }
  })
}

ui <- shinyUI(fluidPage(
  mainPanel(
    tabsetPanel(
      tabPanel("Iris Type", DT::dataTableOutput("iris_type")),
      tabPanel("Filtered Data", DT::dataTableOutput("filtered_data"))
    )
  )
))

shinyApp(ui = ui, server = server)

And another one:

library(shiny)
library(dplyr)
library(tidyr)

data(iris)  

server <- shinyServer(function(input, output) {
  
  iris1 <- reactive({
    iris %>% 
      filter(Species %in% input$select)
  })
  
  output$filtered_data <- DT::renderDataTable({
    datatable(iris1())
  })
})

ui <- shinyUI(fluidPage(
  mainPanel(
    selectInput("select", label=h3("Iris Type"), choices=list('setosa', 'versicolor', 'virginica'),
                selected='setosa', multiple=FALSE),
    DT::dataTableOutput("filtered_data")
    
  )
))

shinyApp(ui = ui, server = server)

When I click on one of the species in the first app, I would like it to link me to the second app instead of another tab, and select the clicked species from the first app (see the picture below).

I figured that I have to change the link from "<a href='#filtered_data'>", unique(iris$Species), "</a>", to the link of my the other app but I don't know how to change the value of my selectInput option in the second app. Please help.

Image explanation


Solution

  • Amending my earlier response, (because, agreed, a simpler solution should be available)

    Instead, here's a solution built on mining the session object:

    if you open the second shiny app via

    <a href="http://server.com/app2?Species=setosa">

    (change server.com/app2 to your actual link) then in that second app, include this for the select object:

    EDIT: Note, since this relies on the session object, your server function will change from function(input,output) to function(input,output,session)

    ui.R:

    htmlOutput('selectSpecies')
    

    server.R:

    output$selectSpecies <- renderUI({
        URLvars <- session$clientData$url_search
        # NOTE: the following regex is not one-size-fits-all
        # if you use multiple inputs, you'll probably need to adjust it
        # also remove special characters, because I want to sanitize our inputs
    
        Species <- gsub('[[:punct:]]','',URLvars)
        Species <- sub('^.*Species(.*$)','\\1',URLvars)
    
        selectInput("select", label=h3("Iris Type"), choices=list('setosa',    'versicolor', 'virginica'),
                selected=ifelse(Species=="",'setosa',Species), multiple=FALSE)
    })
    

    So the session object does contain the portion of the url it was opened with, so it's just a matter of converting that info to a variable we can use.