How do you pass parameters to a shiny app via URL - r

In web browsers you pass parameters to a website like
www.mysite.com/?parameter=1
I have a shiny app and I would like to use the parameter passed in to the site in calculations as an input. So is it possible to do something like www.mysite.com/?parameter=1 and then use input!parameter?
Can you provide any sample code or links?
Thank you

You'd have to update the input yourself when the app initializes based on the URL. You would use the session$clientData$url_search variable to get the query parameters. Here's an example, you can easily expand this into your needs
library(shiny)
shinyApp(
ui = fluidPage(
textInput("text", "Text", "")
),
server = function(input, output, session) {
observe({
query <- parseQueryString(session$clientData$url_search)
if (!is.null(query[['text']])) {
updateTextInput(session, "text", value = query[['text']])
}
})
}
)

Building off of daattali, this takes any number of inputs and does the assigning of values for you for a few different types of inputs:
ui.R:
library(shiny)
shinyUI(fluidPage(
textInput("symbol", "Symbol Entry", ""),
dateInput("date_start", h4("Start Date"), value = "2005-01-01" ,startview = "year"),
selectInput("period_select", label = h4("Frequency of Updates"),
c("Monthly" = 1,
"Quarterly" = 2,
"Weekly" = 3,
"Daily" = 4)),
sliderInput("smaLen", label = "SMA Len",min = 1, max = 200, value = 115),br(),
checkboxInput("usema", "Use MA", FALSE)
))
server.R:
shinyServer(function(input, output,session) {
observe({
query <- parseQueryString(session$clientData$url_search)
for (i in 1:(length(reactiveValuesToList(input)))) {
nameval = names(reactiveValuesToList(input)[i])
valuetoupdate = query[[nameval]]
if (!is.null(query[[nameval]])) {
if (is.na(as.numeric(valuetoupdate))) {
updateTextInput(session, nameval, value = valuetoupdate)
}
else {
updateTextInput(session, nameval, value = as.numeric(valuetoupdate))
}
}
}
})
})
Example URL to test: 127.0.0.1:5767/?symbol=BBB,AAA,CCC,DDD&date_start=2005-01-02&period_select=2&smaLen=153&usema=1

Shiny App: How to Pass Multiple Tokens/Parameters through URL
The standard delimeter for tokens passed through url to shiny app is the & symbol.
Example shiny app code:
server <- function(input, output, session) {
observe({
query <- parseQueryString(session$clientData$url_search)
if (!is.null(query[['paramA']])) {
updateTextInput(session, "InputLabel_A", value = query[['paramA']])
}
if (!is.null(query[['paramB']])) {
updateTextInput(session, "InputLabel_A", value = query[['paramB']])
}
})
# ... R code that makes your app produce output ..
}
Coresponding URL example:
http://localhost.com/?paramA=hello&?paramB=world
Reference: parseQueryString Docs

Building off DeanAttali's idea, this snippet will re-generate the URL at the top so that users can copy the link for sharing to others.
The stringr:: part can probably be enhanced to be more URL-friendly.
library(stringr)
library(glue)
library(shiny)
# http://127.0.0.1:8080/?text=hello+world+I%27m+a+shiny+app
shinyApp(
ui = fluidPage(
textOutput("url"),
textInput("text", "Text", ""),
),
server = function(input, output, session) {
observe({
query <- parseQueryString(session$clientData$url_search)
if (!is.null(query[['text']])) {
updateTextInput(session, "text", value = query[['text']])
}
})
output$url <- renderText({
stringr::str_replace_all(glue::glue("http://127.0.0.1:8080/?text={input$text}"), ' ', '+')
})
},
options=list(port=8080)
)

Related

Communication between modules and looping through values to create several modules

Goal
I have five expectations:
Solution using modules
Communication between modules
Dynamic creation of modules
local storage using shinyStore
Export result in dataframe
What has worked so far
This is a continuation of the following question.
I have a Shiny app that currently has two modules, but I have had issues with both of them communicating. The first module Selects any number of species within a Species pool (SpeciesSelect), this module is in the file R/SpeciesSelect.R within my working directory with the following code.
SpeciesSelect_UI <- function(id, SpeciesList){
ns <- NS(id)
tagList(
shiny::selectizeInput(inputId = ns("SpeciesNames"), label = "SpeciesName",
choices = SpeciesList,
multiple = T)
)
}
SpeciesSelect_Server <- function(id){
moduleServer(id, function(input, output, session) {
# return the reactive here
return(reactive({input$SpeciesNames}))
})
}
And the second module (SpeciesCount) would use those species in order to select how you sample them, and in some cases to count them when the method is equal to pinpoint. This is stored in R/SpeciesCount.R and the code is as follows:
SpeciesCount_UI <- function(id, Species){
ns <- NS(id)
tagList(
shinyMobile::f7Card(
f7Flex(
textOutput(ns("SpeciesAgain")),
uiOutput(ns("Sampling_type_ui")),
uiOutput(ns("SpeciesCount"))
)
)
)
}
SpeciesCount_Server <- function(id, Species){
moduleServer(id, function(input, output, session) {
output$SpeciesAgain <- renderText({Species})
ns <- session$ns
output$Sampling_type_ui <- renderUI({
#req(input$SpeciesName)
req(Species)
f7Select(inputId = ns("Sampling_type"),
label = "Sampling type",
choices = c("5m circle", "15m circle", "Pin-point"))
})
output$SpeciesCount <- renderUI({
if (req(input$Sampling_type) == "Pin-point") {
shinyMobile::f7Stepper(inputId = ns("Species1"), label = "Species count", min = 1, max = 1000, step = 1, value = 1)
}
})
})
}
Each of the modules is working well on its own as shown in the following example:
library(shiny)
library(shinyMobile)
library(shinyStore)
source("R/SpeciesCount.R")
source("R/SpeciesSelect.R")
SpeciesList <- c("Species1", "Species2", "Species3", "Species4", "Species5")
ui = f7Page(
title = "Show navbar",
f7SingleLayout(
navbar = f7Navbar("Hide/Show navbar"),
f7Button(inputId = "toggle", "Toggle navbar", color = "red"),
SpeciesSelect_UI(id = "SpeciesList", SpeciesList = SpeciesList),
lapply(seq_along(SpeciesList), function(i) {
SpeciesCount_UI(id = i, Species = SpeciesList[i])
})
)
)
server = function(input, output, session) {
lapply(seq_along(SpeciesList), function(i) {
SpeciesCount_Server(id = i, Species = SpeciesList[i])
})
observeEvent(input$toggle, {
updateF7Navbar()
})
}
shinyApp(ui, server)
I have 4 issues that are not working well, first, the communication between modules, and then looping through the results of the first module to get several of the second module, the localStorage issue, and finally exporting it to a dataframe
Communication between modules and dynamic UI generation
In order to isolate both issues, for the communication problem, I selected only one species and took out the lapply function to see if I can get the SpeciesCount to recognise the output of the SpeciesSelect_Server and incorporate it into the SpeciesCount module, here is the code I ended up with:
library(shiny)
library(shinyMobile)
library(shinyStore)
source("R/SpeciesCount.R")
source("R/SpeciesSelect.R")
LIST <- c("Species1", "Species2", "Species3", "Species4", "Species5")
ui = f7Page(
title = "Show navbar",
f7SingleLayout(
navbar = f7Navbar("Hide/Show navbar"),
f7Button(inputId = "toggle", "Toggle navbar", color = "red"),
SpeciesSelect_UI(id = "SpeciesList", SpeciesList = LIST),
SpeciesCount_UI(id = "SpeciesCount", Species = SpeciesSelected())
)
)
server = function(input, output, session) {
SpeciesSelected <- SpeciesSelect_Server(id = "SpeciesList")
SpeciesCount_Server(id = "SpeciesCount", Species = SpeciesSelected())
observeEvent(input$toggle, {
updateF7Navbar()
})
}
shinyApp(ui, server)
But the results of the SpeciesSelect module are not generating any UI in the SpeciesCount module
Adding the LocalStorage issue
This app is going to be used in the field, that means, that at time we might get connectivity issues, I have issues at storing the values of the Species Select Module, then for sure I will have issues with the next module this is the shiny app I am using
library(shiny)
library(shinyMobile)
library(shinyStore)
source("R/SpeciesCount.R")
source("R/SpeciesSelect.R")
SpeciesList <- c("Species1", "Species2", "Species3", "Species4", "Species5")
ui = f7Page(
title = "Show navbar",
f7SingleLayout(
navbar = f7Navbar("Hide/Show navbar"),
f7Button(inputId = "toggle", "Toggle navbar", color = "red"),
SpeciesSelect_UI(id = "SpeciesList", SpeciesList = SpeciesList),
lapply(seq_along(SpeciesList), function(i) {
SpeciesCount_UI(id = i, Species = SpeciesList[i])
})
)
)
server = function(input, output, session) {
lapply(seq_along(SpeciesList), function(i) {
SpeciesCount_Server(id = i, Species = SpeciesList[i])
})
observeEvent(input$toggle, {
updateF7Navbar()
})
}
shinyApp(ui, server)
And I modified the species select for that also
SpeciesSelect_UI <- function(id, SpeciesList){
ns <- NS(id)
tagList(
shiny::selectizeInput(inputId = ns("SpeciesNames"), label = "SpeciesName",
choices = SpeciesList,
multiple = T)
)
}
SpeciesSelect_Server <- function(id){
moduleServer(id, function(input, output, session) {
ns <- session$ns
# return the reactive here
observeEvent(input$save, {
updateStore(session, name = ns("SpeciesNames"), input$SpeciesNames)
}, ignoreInit = TRUE)
observeEvent(input$clear, {
# clear current user inputs:
updateTextInput(session, inputId = ns("SpeciesNames"), value = "")
# clear shinyStore:
updateStore(session, name = ns("SpeciesNames"), value = "")
}, ignoreInit = TRUE)
return(reactive({ns(input$SpeciesNames)}))
})
}
But nothing gets stored. Maybe creating a module for shiny store is needed?
Export as a dataframe
This one is tied two point 2:
So lets say I am in the following input set:
The idea would be to generate a reactive that has the following that frame, that I can then export as a CSV file. I think I can handle the export, but I am unsure on how to generate the data.frame from the dynamic UI:
data.frame(Species = c("Species1", "Species2", "Species3"), Method = c("Pin-point","5m circle", "15m circle"), abundance = c(5, 1, 1))
Your first module is probably already silently returning the reactive but for clarity you can make it explicit. In you first module, return a reactive:
SpeciesSelect_Server <- function(id){
moduleServer(id, function(input, output, session) {
# return the reactive here
return(reactive({input$SpeciesNames}))
})
}
Now call the module AND assign its output a name where you'd like to use it (in another module or in your app server), like this:
selected_species <- SpeciesSelect_Server(id = "SpeciesList")
Now selected_species can be called, observed, etc with:
selected_species()

Updating private but not UI in reactive element

I have an R6 class that I am using to organize my shiny application. Essentially, I want to connect different R6 classes for an experimental interface I am creating and want to reuse my code. As a simplified working example, see the code below.
library(R6)
library(stringi)
library(shiny)
df <- data.frame(dp = c("dp1", "dp2", "dp3"), desc = c("problem 1", "problem 2", "problem 3"))
app <- R6::R6Class(classname = "App",
private = list(
#unique string id
..id = stringi::stri_rand_strings(1, 18),
#the data to be iterated through
..df = df,
#counter to update text
..counter = 1,
#initiating the dp and desc
..dp = 'dp1',
..desc = 'problem 1',
#the underlying server, to be created like a normal server
.server = function(input, output, session){
output$text <- renderText({
private$..desc
})
observeEvent(input$button, {
private$..counter <- private$..counter + 1
self$update_private()
#check the private content since the print is not updating
print(private$..counter)
print(private$..dp)
print(private$..desc)
})
}
),
public = list(
#create names for ui elements
button = NULL,
text = NULL,
initialize = function(){
self$button <- self$get_id("button")
self$text <- self$get_id("text")
self$update_private()
},
#gives ui outputs unique names tied to the user's id
get_id = function(name, ns = NS(NULL)){
ns <- NS(ns(private$..id))
id <- ns(name)
return(id)
},
#automatically updates the private field based on the counter
update_private = function(){
if(private$..counter == 1){
private$..dp <- "dp1"
} else if(private$..counter == 2){
private$..dp <- "dp2"
} else{
private$..dp <- "dp3"
}
private$..desc <- private$..df[private$..df$dp == private$..dp, "desc"]
},
ui = function(){
fluidPage(
h1("An Example"),
mainPanel(
textOutput(self$text)),
sidebarPanel(
shiny::actionButton(inputId = self$button,
label = 'Update!',
width = '100%'
))
)
},#end ui
server = function(input, output, session){
callModule(module = private$.server, id = private$..id)
}
)
)
test <- app$new()
ui <- test$ui()
server <- function(input, output, session) {
test$server()
}
shinyApp(ui = ui, server = server)
What I want: when someone clicks the action button, the reactive ui will update and the desired text from the data frame will be sliced and displayed.
What I am getting: the internal private data fields are updating but the reactive ui elements are not.
Any ideas what could be causing this or a workaround? I thought about externally trying to use the observe event and then reinitiating the class with a new counter number. But I also can't seem to figure out that option either.
Appreciate your help!
For anyone that comes across this problem... I figured out that even though the private is updating, and even though render is technically a reactive environment, you need to have your data stored publically in a reactive field.
library(R6)
library(stringi)
library(shiny)
df <- data.frame(dp = c("dp1", "dp2", "dp3"), desc = c("problem 1", "problem 2", "problem 3"))
app <- R6::R6Class(classname = "App",
private = list(
#unique string id
..id = stringi::stri_rand_strings(1, 18),
#the data to be iterated through
..df = df,
#counter to update text
..counter = 0,
#initiating the dp and desc
..dp = NA,
..desc = NA,
#the underlying server, to be created like a normal server
.server = function(input, output, session){
output$text <- renderText({
self$desc$text
})
observeEvent(input$button, {
private$..counter <- private$..counter + 1
self$update_private()
self$desc$text <- private$..desc
#check the private content since the print is not updating
print(private$..counter)
print(private$..dp)
print(private$..desc)
})
}
),
active = list(
.counter = function(value){
if(missing(value)){
private$..counter
}else{
private$..counter <- value
}
}
),
public = list(
#create names for ui elements
button = NULL,
text = NULL,
#Need this to update the text***************
desc = reactiveValues(text = NA),
initialize = function(counter = self$.counter){
self$.counter <- counter
self$button <- self$get_id("button")
self$text <- self$get_id("text")
self$update_private()
self$desc$text <- private$..desc
},
#gives ui outputs unique names tied to the user's id
get_id = function(name, ns = NS(NULL)){
ns <- NS(ns(private$..id))
id <- ns(name)
return(id)
},
#automatically updates the private field based on the counter
update_private = function(){
if(private$..counter == 1){
private$..dp <- "dp1"
} else if(private$..counter == 2){
private$..dp <- "dp2"
} else{
private$..dp <- "dp3"
}
private$..desc <- private$..df[private$..df$dp == private$..dp, "desc"]
},
ui = function(){
fluidPage(
h1("An Example"),
mainPanel(
textOutput(self$text)),
sidebarPanel(
shiny::actionButton(inputId = self$button,
label = 'Update!',
width = '100%'
))
)
},#end ui
server = function(input, output, session){
counter <- reactiveVal(private$..counter)
callModule(module = private$.server, id = private$..id)
}
)
)
test <- app$new(counter = 1)
ui <- test$ui()
server <- function(input, output, session) {
test$server()
}
shinyApp(ui = ui, server = server)

shiny module: update color of button

i am struggling with the logic of updating a button in the ui based on code that is living in a module. When I click the button i want it to change the colour but nothing happens. I understand to make ui input reactive in order to use it in the server module but i do not get it working the other way around. Help (and some explanation) is highly appreciated!
here is my code: (I left the save to csv part upon click as i got that to work).
library(shiny)
library(shinyBS)
module_company_ui<-function(id){
# `NS(id)` returns a namespace function, which was save as `ns` and will
# invoke later.
ns <- NS(id)
tagList(
radioButtons(ns("company_name"), label= "Is the << COMPANY NAME >> correct?",
c("choose from below" = "10",
"correct" = "0.15",
"correct, but some noise" = "0.075",
"not sure" = "0.05",
"wrong" = "0"),selected = character(0)),
textOutput(ns("txt")),
bsButton(ns('save_inputs'), " Save", type="action", block=TRUE, style="info", icon=icon(name="save"))
)
}
module_save_inputs<-function(id, value_company){
moduleServer(
id,
## Below is the module function
function(input, output, session) {
save<-reactive(input$save_inputs)
observeEvent(save(), {
updateButton(session, "save_inputs",label = " Save", block = T, style = "success", icon=icon(name="save"))
})
})
}
ui <- fluidPage(
module_company_ui("company")
)
server <- function(input, output, session) {
module_save_inputs("company")
}
shinyApp(ui, server)
You need namespace ns for the updateButton. Try this
module_save_inputs<-function(id, value_company){
moduleServer(
id,
## Below is the module function
function(input, output, session) {
ns <- session$ns
save<-reactive(input$save_inputs)
observeEvent(save(), {
updateButton(session, ns("save_inputs"),label = " Save", block = T, style = "success", icon=icon(name="save"))
})
})
}

R Shiny - Saving results of dynamically created modules

I encountered the following problem that I have tried to summarize in this minimal reproducible example.
The app should be able to dynamically create modules and render the UI of the module - obj_UI in my example - in a tab of the tabsetpanel objTP. Each of this modules should render a R6 object of type objR6. I would like to save the resulting R6 objects into a reactiveValues variable called objCollection and display it in the verbatimTextOutput called displayValues.
When clicking on the input$addObject button, I get the error message "Error in <-: cannot add bindings to a locked environment". I believe the problem lies in the observeEvent at the very end of the example, but cannot figure what it is.
Any help would be much appreciated!
library(shiny)
library(R6)
# Simple R6 object
objR6 <- R6::R6Class(
"objR6",
public = list(
identifier = NULL,
selected_value = NULL,
initialize = function(identifier) {
self$identifier <- identifier
}
)
)
# Module Ui
obj_UI <- function(id) {
tagList(
selectInput(NS(id, "value"), "Chose Value", letters)
)
}
# Module Server
obj_Server <- function(id) {
moduleServer(id, function(input, output, session) {
obj <- reactiveVal(objR6$new(id))
observeEvent(input$value, {
newObj <- obj()$clone()
newObj$selectec_value <- input$value
obj(newObj)
})
return(reactive(obj()))
})
}
# Shiny App
ui <- fluidPage(
fluidPage(
selectInput("objSelection", "Select Object",
choices = "",
selectize = FALSE,
size = 10),
actionButton("addObject", "Add Object"),
actionButton("rmvObject", "Remove Object"),
tabsetPanel(id = "objTP"),
verbatimTextOutput("displayValues")
)
)
server <- function(input, output, session) {
objCount <- reactiveVal(0)
objCollection <- reactiveValues(objects = list())
# Reaction on action button "addObject"
observeEvent(input$addObject, {
# Add another item
objCount(objCount() + 1)
newObjName <- paste0("Object_", objCount())
updateSelectInput(session, "objSelection", choices = c(paste0("Object_", 1:objCount())))
# Append the object tabset panel
appendTab("objTP", tabPanel(newObjName, obj_UI(newObjName)), select = TRUE)
})
# Reaction on action button "rmvObject"
observeEvent(input$rmvObject, {
delObjName <- paste0("Object_", objCount())
objCount(objCount() - 1)
updateSelectInput(session, "objSelection", choices = c(paste0("Object_", 1:objCount())))
removeTab("objTP", target = delObjName)
})
# Implement the server side of module
observeEvent(objCount(), {
if (objCount() > 0) {
for (i in 1:objCount()) {
identifier <- paste0("Object_", i)
observeEvent(obj_Server(identifier), {
objCollection$objects[[identifier]] <- obj_Server(identifier)
})
}
}
# Ouput the selected values
output$displayValues <- renderPrint({
reactiveValuesToList(objCollection)
})
})
}
shinyApp(ui, server)
The following minimal reproducible example is an answer to the problem above. In comparison to the code above I corrected a typo in the server function of the module and also put the initialization of the server part in the observeEvent for the input$addObject and removed the observeEvent for objCount().
library(shiny)
library(R6)
# Simple R6 object
objR6 <- R6::R6Class(
"objR6",
public = list(
identifier = NULL,
selected_value = NULL,
initialize = function(identifier) {
self$identifier <- identifier
}
)
)
# Module Ui
obj_UI <- function(id) {
tagList(
selectInput(NS(id, "value"), "Chose Value", letters)
)
}
# Module Server
obj_Server <- function(id) {
moduleServer(id, function(input, output, session) {
obj <- reactiveVal(objR6$new(id))
observeEvent(input$value, {
newObj <- obj()$clone()
newObj$selected_value <- input$value
obj(newObj)
})
return(reactive(obj()))
})
}
# Shiny App
ui <- fluidPage(
fluidPage(
selectInput("objSelection", "Select Object",
choices = "",
selectize = FALSE,
size = 10),
actionButton("addObject", "Add Object"),
actionButton("rmvObject", "Remove Object"),
tabsetPanel(id = "objTP"),
verbatimTextOutput("displayValues")
)
)
server <- function(input, output, session) {
objCount <- reactiveVal(0)
objCollection <- reactiveValues(objects = list())
# Reaction on action button "addObject"
observeEvent(input$addObject, {
# Add another item
objCount(objCount() + 1)
newObjName <- paste0("Object_", objCount())
updateSelectInput(session, "objSelection", choices = c(paste0("Object_", 1:objCount())))
# Append the object tabset panel
appendTab("objTP", tabPanel(newObjName, obj_UI(newObjName)), select = TRUE)
# Add the server component of the module
observeEvent(obj_Server(newObjName), {
objCollection$objects[[newObjName]] <- obj_Server(newObjName)
})
})
# Reaction on action button "rmvObject"
observeEvent(input$rmvObject, {
delObjName <- paste0("Object_", objCount())
if (objCount() > 0) {
objCount(objCount() - 1)
removeTab("objTP", target = delObjName)
objCollection$objects[[delObjName]] <- NULL
if (objCount() > 0) {
updateSelectInput(session, "objSelection", choices = c(paste0("Object_", 1:objCount())))
} else {
updateSelectInput(session, "objSelection", choices = "")
}
}
})
# Ouput the selected values
output$displayValues <- renderPrint({
lapply(reactiveValuesToList(objCollection)$objects, function(i) {i()})
})
}
shinyApp(ui, server)

Select tabPanel and a row within a data table on shiny via URL doesn't work in combination

I am trying to select a specific tab of my navbarPage and at the same time selecting a row of my datatable. This works fine for the first tab but not for a different tab. Can anyone help me on this?
library(DT)
library(shiny)
ui <- navbarPage(
id = "tabs",
'URL GET test',
tabPanel(
'welcome',
value='welcome',
h2('hi'),
DT::dataTableOutput("mytable2")
),
tabPanel(
"mtcars",
value='mtcars',
textInput("text", "Text", ""),
DT::dataTableOutput("mytable1")
)
)
server <- function(input, output, session) {
observe({
query <- parseQueryString(session$clientData$url_search)
print(query)
if (!is.null(query[['data']])) {
text_string <- query[['data']]
updateNavbarPage(session, inputId="tabs", selected=query[['data']])
}
if (!is.null(query[['text']])) {
text_string <- query[['text']]
updateTextInput(session, "text", value = text_string)
}
if (!is.null(query[['row']])) {
DT::selectRows(mytable_proxy1, as.numeric(query[['row']]))
DT::selectRows(mytable_proxy2, as.numeric(query[['row']]))
}
})
output$mytable1 = DT::renderDataTable({mtcars})
mytable_proxy1 = DT::dataTableProxy('mytable1')
output$mytable2 = DT::renderDataTable({mtcars})
mytable_proxy2 = DT::dataTableProxy('mytable2')
}
shinyApp(ui, server)
So by using the following URL (IP and port might be different), I can select a row on the first tab http://127.0.0.1:6583/?row=2 (working), with http://127.0.0.1:6583/?data=mtcars&text=bla (working) I can directly select the second tab and also update the text field.
But my goal is to select the second tab and select a specific row like I did for the first tab http://127.0.0.1:6583/?data=mtcars&row=2 (not working).
For example explicitly selecting the first tab and a row http://127.0.0.1:6583/?data=welcome&row=2 (works).
I suspect that the issue here is the order of operations in which Shiny executes the statements. In this case, when you try http://127.0.0.1:6583/?data=mtcars&row=2, the observer for the query first selects the mtcars tab and immediately tries to set the selected row through the DT proxy. However, the second table has not been rendered yet, it is only rendered after the observer finishes running. This is also why http://127.0.0.1:6583/?data=welcome&row=2 runs fine, since the app opens on the welcome tab and it renders the datatable before the observer fires.
One work around would be to store the selected row value in a reactiveVal, and use this value while rendering the datatable. A working example is given below, hope this helps!
library(DT)
library(shiny)
ui <- navbarPage(
id = "tabs",
'URL GET test',
tabPanel(
'welcome',
value='welcome',
h2('hi'),
DT::dataTableOutput("mytable2")
),
tabPanel(
"mtcars",
value='mtcars',
textInput("text", "Text", ""),
DT::dataTableOutput("mytable1")
)
)
server <- function(input, output, session) {
observe({
query <- parseQueryString(session$clientData$url_search)
print(query)
if (!is.null(query[['data']])) {
text_string <- query[['data']]
updateNavbarPage(session, inputId="tabs", selected=query[['data']])
}
if (!is.null(query[['text']])) {
text_string <- query[['text']]
updateTextInput(session, "text", value = text_string)
}
if (!is.null(query[['row']])) {
selected_row(as.numeric(query[['row']]))
}
})
selected_row <- reactiveVal()
output$mytable1 = DT::renderDataTable({
datatable(mtcars ,selection = list(mode = 'multiple', selected = selected_row()))
})
mytable_proxy1 = DT::dataTableProxy('mytable1')
output$mytable2 = DT::renderDataTable({
datatable(mtcars ,selection = list(mode = 'multiple', selected = selected_row()))
})
mytable_proxy2 = DT::dataTableProxy('mytable2')
}
shinyApp(ui, server)

Resources