how to display dynamic tabPanels with DT inside multiple nested modules - r

I really need help on the following code, I use 2 nested modules to display sampledata in multiple tabPanels (inside tabsetPanel) by certain columns, but the table is not display, I cant found any bugs inside yet.
PS: this is just an reproducible example, the sampledata is uploaded by user in real scenario
library(shiny)
library(shinydashboard)
library(DT)
ui <- function() {
dashboardPage(
dashboardHeader(title = "abc"),
dashboardSidebar(uiOutput("sidebarpanel")),
dashboardBody(uiOutput("body")))
}
server <- function(input, output, session) {
output$sidebarpanel <- renderUI({
tags$div(
sidebarMenu(id = "tabs",
menuItem("Data", tabName = "data"))
)
})
output$body <- renderUI({
tabItems(ui_data1("data1", tabName = "data"))
})
input_data1 <- new.env()
input_data1$a <- reactive(1)
input_data1$b <- reactive(2)
input_data2 <- server_data1("data1", input_data1)
}
ui_data1 <- function(id, tabName){
ns <- NS(id)
tabItem(tabName = tabName,
uiOutput(ns("body")))
}
server_data1 <- function(id, input_data1) {
ns <- NS(id)
moduleServer(id, function(input, output, session) {
output$body <- renderUI({
tabsetPanel(
ui_data2(ns("info1"), "Info1")
)
})
data2 <- new.env()
data2$input_data2 <- server_data2("info1", input_data1)
return(data2)
})
}
ui_data2 <- function(id, title) {
ns <- NS(id)
tabPanel(title = title,
uiOutput(ns("body")))
}
server_data2 <- function(id, input_data1) {
ns <- NS(id)
moduleServer(id, function(input, output, session) {
c <- eventReactive(input_data1$a(), {
2
})
sampledata <- reactive(mtcars)
output$body <- renderUI({
all_cyl <- unique(sampledata()$cyl)
tbl_by_cyl <- lapply(seq_along(all_cyl), function(i) {
tabPanel(all_cyl[i],
column(12, br(),
box(width = "auto",
DT::dataTableOutput(ns(paste0("cyl", i)),
width = "100%"))))
})
do.call(tabsetPanel, tbl_by_cyl)
})
observe({
sampledata <- sampledata()
all_cyl <- unique(sampledata$cyl)
lapply(seq_along(all_cyl), function(i) {
output[[paste0("cyl", i)]] <- DT::renderDataTable({
datatable(sampledata[sampledata$cyl == all_cyl[i], ])
})
})
})
return(sampledata)
})
}
shinyApp(ui, server)
output:
output of above code

You were very close. You just needed ns <- session$ns in server_data1 and server_data2. Try this
library(shiny)
library(shinydashboard)
library(DT)
ui <- function() {
dashboardPage(
dashboardHeader(title = "abc"),
dashboardSidebar(uiOutput("sidebarpanel")),
dashboardBody(uiOutput("body")))
}
server <- function(input, output, session) {
output$sidebarpanel <- renderUI({
tags$div(
sidebarMenu(id = "tabs",
menuItem("Data", tabName = "data"))
)
})
output$body <- renderUI({
tabItems(ui_data1("data1", tabName = "data"))
})
input_data1 <- new.env()
input_data1$a <- reactive(1)
input_data1$b <- reactive(2)
input_data2 <- server_data1("data1", input_data1)
}
ui_data1 <- function(id, tabName){
ns <- NS(id)
tabItem(tabName = tabName,
uiOutput(ns("body1")))
}
server_data1 <- function(id, input_data1) {
#ns <- NS(id)
moduleServer(id, function(input, output, session) {
ns <- session$ns
output$body1 <- renderUI({
tabsetPanel(
ui_data2(ns("info1"), "Info1")
)
})
data2 <- new.env()
data2$input_data2 <- server_data2("info1", input_data1)
return(data2)
})
}
ui_data2 <- function(id, title) {
ns <- NS(id)
tabPanel(title = title,
uiOutput(ns("body2")))
}
server_data2 <- function(id, input_data1) {
#ns <- NS(id)
moduleServer(id, function(input, output, session) {
ns <- session$ns
c <- eventReactive(input_data1$a(), {
2
})
sampledata <- reactive(mtcars)
output$body2 <- renderUI({
all_cyl <- unique(sampledata()$cyl)
tbl_by_cyl <- lapply(seq_along(all_cyl), function(i) {
tabPanel(all_cyl[i],
fluidRow(column(12, br(),
shinydashboard::box( width = "auto",
DTOutput(ns(paste0("cyl", i)),width = "100%")))))
})
do.call(tabsetPanel, tbl_by_cyl)
})
observe({
sampledata <- sampledata()
all_cyl <- unique(sampledata$cyl)
lapply(seq_along(all_cyl), function(i) {
output[[paste0("cyl", i)]] <- renderDT({
datatable(sampledata[sampledata$cyl == all_cyl[i], ])
})
})
})
return(sampledata)
})
}
shinyApp(ui, server)

Related

How to get a click event on a graph in module shiny

I'm new to shiny.
When I try to handle a click or brush event without using modules, everything works ok.
What should I do to make the events work inside the module?
There is simple code
#MODULE
plUI <- function(id) {
tagList(
selectInput(NS(id, "var"), "Variable", choices = names(mtcars)),
numericInput(NS(id, "bins"), "bins", value = 10, min = 1),
plotOutput(NS(id, "hist"), click = "plot_click"),
verbatimTextOutput("info")
)
}
plServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$hist <- renderPlot({
plot(data(), breaks = input$bins, main = input$var)
}, res = 96)
output$info <- renderPrint({
req(input$plot_click)
x <- round(input$plot_click$x, 2)
y <- round(input$plot_click$y, 2)
cat("[", x, ", ", y, "]", sep = "")
})
})
}
#------------------------------UI-------------------------------------
ui <- fluidPage(
ui <- fluidPage(
plUI("p1"),
)
)
#------------------------------SERVER-------------------------------------
server <- function(input, output, session) {
plServer("p1")
}
shinyApp(ui, server)
Instead of NS(id, "var") for each id, you can do ns <- NS(id) and then use ns("var") and so on.
plot_click is also an id so wrap it in ns as well.
You had forgotten NS in verbatimTextOutput("info").
The main ui had two fluidPage that probably was by mistake so removed it.
library(shiny)
plUI <- function(id) {
ns <- NS(id)
tagList(
selectInput(ns("var"), "Variable", choices = names(mtcars)),
numericInput(ns("bins"), "bins", value = 10, min = 1),
plotOutput(ns("hist"), click = ns("plot_click")),
verbatimTextOutput(ns("info"))
)
}
plServer <- function(id) {
moduleServer(id, function(input, output, session) {
ns <- session$ns
data <- reactive(mtcars[[input$var]])
output$hist <- renderPlot({
plot(data(), breaks = input$bins, main = input$var)
}, res = 96)
output$info <- renderPrint({
req(input$plot_click)
x <- round(input$plot_click$x, 2)
y <- round(input$plot_click$y, 2)
cat("[", x, ", ", y, "]", sep = "")
})
})
}
#------------------------------UI-------------------------------------
ui <- fluidPage(
plUI("p1")
)
#------------------------------SERVER-------------------------------------
server <- function(input, output, session) {
plServer("p1")
}
shinyApp(ui, server)

How to loop through bookmark state inputs and restore in the right order?

I have 3 modules to get histograms, boxplots and tables. The reactivity and saving the state works great, but I'm unable to restore them in the right order.
I've tried onRestored which jumbles the order or groups the modules. I've also tried to reset the inputs so that further saving and reloading doesn't change the order. onRestore is close but it reorders the output in the reverse order.
library(shiny)
library(janitor)
histogramUI <- function(id,var,bins) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var"), "Variable", choices = names(mtcars),selected=var),
numericInput(NS(id, "bins"), "bins", value = bins, min = 1)),
column(8, plotOutput(NS(id, "hist"))))
)
}
histogramServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$hist <- renderPlot({
hist(data(), breaks = input$bins, main = input$var)
}, res = 96)
})
}
tableUI <- function(id,var,bins) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var"), "Variable", choices = names(mtcars),selected=var),
column(8, tableOutput(NS(id, "tab")))))
)
}
tableServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$tab <- renderTable({
tabyl(data(), main = input$var)
})
})
}
boxUI <- function(id,var) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var2"), "Variable", choices = names(mtcars),selected=var),
column(8, plotOutput(NS(id, "box"))))
))
}
boxServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var2]])
output$box <- renderPlot({
boxplot(data(), main = input$var2)
})
})
}
ui <- function(request){
fluidPage(
bookmarkButton(),
actionButton("add", "Add Histogram"),
actionButton("add2", "Add Boxplot"),
actionButton("add3", "Add Table"),
div(id = "add_here")
)
}
server <- function(input, output, session) {
observeEvent(input$add, {
bins <- 10
histogramServer(paste0("hist_", input$add))
insertUI(selector = "#add_here", ui = histogramUI(paste0("hist_", input$add),input$var,bins))#}
})
observeEvent(input$add2, {
boxServer(paste0("box_", input$add2))
insertUI(selector = "#add_here", ui = boxUI(paste0("box_", input$add2), input$var2))
})
observeEvent(input$add3, {
tableServer(paste0("tab_", input$add3))
insertUI(selector = "#add_here", ui = tableUI(paste0("tab_", input$add3), input$var))
})
onRestored(function(state){
hist_var <- stringr::str_extract(names(state$input),'hist.*var')
hist_var <- sort(hist_var[!is.na(hist_var)])
hist_bin <- stringr::str_extract(names(state$input),'hist.*bin')
hist_bin <- sort(hist_bin[!is.na(hist_bin)])
box_var <- stringr::str_extract(names(state$input),'box.*var2')
box_var <- sort(box_var[!is.na(box_var)])
tab_var <- stringr::str_extract(names(state$input),'tab.*var')
tab_var <- sort(tab_var[!is.na(tab_var)])
print(hist_var)
print(box_var)
print(tab_var)
if (length(hist_var)>1) {
for (i in 1:(length(hist_var)-1)) {
histogramServer(paste0("hist_", i))
insertUI(selector = "#add_here", ui = histogramUI(paste0("hist_", i),state$input$hist_var[i],state$input$hist_bin[i]))
}
}
if (length(box_var)>1) {
for (i in 1:(length(box_var)-1)) {
boxServer(paste0("box_", i))
insertUI(selector = "#add_here", ui = boxUI(paste0("box_", i),state$input$box_var[i]))
}
}
if (length(tab_var)>1) {
for (i in 1:(length(tab_var)-1)) {
tableServer(paste0("tab_", i))
insertUI(selector = "#add_here", ui = tableUI(paste0("tab_", i),state$input$tab_var[i]))
}
}
hist_var <- NULL
hist_bin <- NULL
box_var <- NULL
tab_var <- NULL
})
}
shinyApp(ui, server, enableBookmarking = "server")
You could use onBookmark to save state$exclude which gives the order of the modules.
The buttons should also be excluded from bookmarking with setBookmarkExclude :
library(shiny)
library(janitor)
histogramUI <- function(id,var,bins) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var"), "Variable", choices = names(mtcars),selected=var),
numericInput(NS(id, "bins"), "bins", value = bins, min = 1)),
column(8, plotOutput(NS(id, "hist"))))
)
}
histogramServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$hist <- renderPlot({
hist(data(), breaks = input$bins, main = input$var)
}, res = 96)
})
}
tableUI <- function(id,var,bins) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var"), "Variable", choices = names(mtcars),selected=var),
column(8, tableOutput(NS(id, "tab")))))
)
}
tableServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$tab <- renderTable({
tabyl(data(), main = input$var)
})
})
}
boxUI <- function(id,var) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var2"), "Variable", choices = names(mtcars),selected=var),
column(8, plotOutput(NS(id, "box"))))
))
}
boxServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var2]])
output$box <- renderPlot({
boxplot(data(), main = input$var2)
})
})
}
ui <- function(request){
fluidPage(
bookmarkButton(),
actionButton("add", "Add Histogram"),
actionButton("add2", "Add Boxplot"),
actionButton("add3", "Add Table"),
div(id = "add_here")
)
}
server <- function(input, output, session) {
setBookmarkExclude(c('add','add2','add3'))
add_id <- reactiveVal(0)
add2_id <- reactiveVal(0)
add3_id <- reactiveVal(0)
observeEvent(input$add, {
bins <- 10
histogramServer(paste0("hist_", input$add+add_id()))
insertUI(selector = "#add_here", ui = histogramUI(paste0("hist_", input$add+add_id()),input$var,bins))#}
})
observeEvent(input$add2, {
boxServer(paste0("box_", input$add2+add2_id())) #changed add_id() to add2_id()
insertUI(selector = "#add_here", ui = boxUI(paste0("box_", input$add2+add2_id()), input$var2))
})
observeEvent(input$add3, {
tableServer(paste0("tab_", input$add3+add3_id()))
insertUI(selector = "#add_here", ui = tableUI(paste0("tab_", input$add3+add3_id()), input$var))
})
onBookmark(function(state) {
state$values$modules <- state$exclude
state$values$add <- state$input$add + add_id()
state$values$add2 <- state$input$add2 + add2_id()
state$values$add3 <- state$input$add3 + add3_id()
})
onRestore(function(state){
add_id(state$values$add)
add2_id(state$values$add2)
add3_id(state$values$add3)
modules <- state$values$modules
if (length(modules)>1) {
for (i in 1:(length(modules))) {
if (substr(modules[i],1,4)=='hist') {
histogramServer(modules[i])
insertUI(selector = "#add_here", ui = histogramUI(modules[i],paste0(modules[i],"-var"),paste0(modules[i],"-bin")))
}
if (substr(modules[i],1,3)=='box') {
boxServer(modules[i])
insertUI(selector = "#add_here", ui = boxUI(modules[i],paste0(modules[i],"-var")))
}
if (substr(modules[i],1,3)=='tab') {
tableServer(modules[i])
insertUI(selector = "#add_here", ui = tableUI(modules[i],paste0(modules[i],"-var")))
}
}
}
})
}
shinyApp(ui, server, enableBookmarking = "server")

How to save and restore bookmark state using rds file instead of copying and pasting url?

I'm trying to run a shiny app locally on my desktop and I'm looking for a way to download and upload the bookmark state as an rds file instead of copying and pasting a url. I've tried workarounds but they are not as helpful as using shiny's bookmark functions and features. Here is an example app which has the bookmark function. I'm trying to convert this into an app that can download and upload rds file to save and restore the state. Any help will be greatly appreciated.
library(shiny)
library(janitor)
histogramUI <- function(id,var,bins) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var"), "Variable", choices = names(mtcars),selected=var),
numericInput(NS(id, "bins"), "bins", value = bins, min = 1)),
column(8, plotOutput(NS(id, "hist"))))
)
}
histogramServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$hist <- renderPlot({
hist(data(), breaks = input$bins, main = input$var)
}, res = 96)
})
}
tableUI <- function(id,var,bins) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var"), "Variable", choices = names(mtcars),selected=var),
column(8, tableOutput(NS(id, "tab")))))
)
}
tableServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var]])
output$tab <- renderTable({
tabyl(data(), main = input$var)
})
})
}
boxUI <- function(id,var) {
tagList(
fluidRow(column( 4, selectInput(NS(id, "var2"), "Variable", choices = names(mtcars),selected=var),
column(8, plotOutput(NS(id, "box"))))
))
}
boxServer <- function(id) {
moduleServer(id, function(input, output, session) {
data <- reactive(mtcars[[input$var2]])
output$box <- renderPlot({
boxplot(data(), main = input$var2)
})
})
}
ui <- function(request){
fluidPage(
bookmarkButton(),
actionButton("add", "Add Histogram"),
actionButton("add2", "Add Boxplot"),
actionButton("add3", "Add Table"),
div(id = "add_here")
)
}
server <- function(input, output, session) {
setBookmarkExclude(c('add','add2','add3'))
add_id <- reactiveVal(0)
add2_id <- reactiveVal(0)
add3_id <- reactiveVal(0)
observeEvent(input$add, {
bins <- 10
histogramServer(paste0("hist_", input$add+add_id()))
insertUI(selector = "#add_here", ui = histogramUI(paste0("hist_", input$add+add_id()),input$var,bins))#}
})
observeEvent(input$add2, {
boxServer(paste0("box_", input$add2+add2_id())) #changed add_id() to add2_id()
insertUI(selector = "#add_here", ui = boxUI(paste0("box_", input$add2+add2_id()), input$var2))
})
observeEvent(input$add3, {
tableServer(paste0("tab_", input$add3+add3_id()))
insertUI(selector = "#add_here", ui = tableUI(paste0("tab_", input$add3+add3_id()), input$var))
})
onBookmark(function(state) {
state$values$modules <- state$exclude
state$values$add <- state$input$add + add_id()
state$values$add2 <- state$input$add2 + add2_id()
state$values$add3 <- state$input$add3 + add3_id()
})
onRestore(function(state){
add_id(state$values$add)
add2_id(state$values$add2)
add3_id(state$values$add3)
modules <- state$values$modules
if (length(modules)>1) {
for (i in 1:(length(modules))) {
if (substr(modules[i],1,4)=='hist') {
histogramServer(modules[i])
insertUI(selector = "#add_here", ui = histogramUI(modules[i],paste0(modules[i],"-var"),paste0(modules[i],"-bin")))
}
if (substr(modules[i],1,3)=='box') {
boxServer(modules[i])
insertUI(selector = "#add_here", ui = boxUI(modules[i],paste0(modules[i],"-var")))
}
if (substr(modules[i],1,3)=='tab') {
tableServer(modules[i])
insertUI(selector = "#add_here", ui = tableUI(modules[i],paste0(modules[i],"-var")))
}
}
}
})
}
shinyApp(ui, server, enableBookmarking = "server")
This question is also posted here

How to find the clicked element in DiagrammeR output produced by a Shiny module

I need to identify which node in a DiagrammeR output has been clicked in a Shiny app. Following this post, I can get the information I need when the output is not produced by a module. But in a module (my real use case), the same logic seems not to work. I can't see why, but I did notice that the DiagrammeR nodes appear not to respect the module's namespace (that is, the first node's id is node1 rather than <namespace>-node1).
What am I doing wrong, or is this a bug in DiagrammeR?
Here's my sample code.
library(shiny)
library(DiagrammeR)
library(shinyjs)
texts <- c("Clicked on A", "Clicked on B")
moduleUI <- function(id) {
ns <- NS(id)
tagList(uiOutput(ns("tooltip")), grVizOutput(ns("tree")))
}
moduleController <- function(input, output, session) {
ns <- session$ns
jsCode <- paste0("Shiny.onInputChange('", ns("clickedElemNr"), "',", 1:2, ")")
observeEvent(input$clickedElemNr, {
print(ns("observeEvent[clickedElemNr]"))
output$tooltip <- renderUI({
textInput(inputId=ns("x"), label="x", value=texts[input$clickedElemNr])
})
})
observe({
output$tooltip <- renderUI({textInput(inputId=ns("x"), label="x", value="Click an element")})
for (i in 1:length(jsCode)) {
local({
jsToAdd <- jsCode[i]
shinyjs::onclick(ns(paste0("node", i)), runjs(jsToAdd))
})
}
})
output$tree <- renderGrViz({
grViz("digraph test {A; B; A -> B;}")
})
}
ui <- fluidPage(
useShinyjs(),
column(width=4, wellPanel("No module", uiOutput("tooltip"), grVizOutput("tree"))),
column(width=4, wellPanel("Module 1", moduleUI("mod1")))
)
server <- function(input, output) {
jsCode <- paste0("Shiny.onInputChange('clickedElemNr',", 1:2, ")")
callModule(moduleController, "mod1")
observeEvent(input$clickedElemNr, {
print("observeEvent[clickedElemNr]")
output$tooltip <- renderUI({
textInput(inputId="x", label="x", value=texts[input$clickedElemNr])
})
})
observe({
output$tooltip <- renderUI({textInput(inputId="x", label="x", value="Click an element")})
for (i in 1:length(jsCode)) {
local({
jsToAdd <- jsCode[i]
shinyjs::onclick(paste0("node", i), runjs(jsToAdd))
})
}
})
output$tree <- renderGrViz({
grViz("digraph test {A; B; A -> B;}")
})
}
shinyApp(ui = ui, server = server)
I've answered my own question, based on this issue in the DiagrammeR GitHub repository, with no need for javascript or other complications.
library(shiny)
library(DiagrammeR)
moduleUI <- function(id) {
ns <- NS(id)
tagList(
verbatimTextOutput(ns("print")),
grVizOutput(ns("tree"))
)
}
moduleController <- function(input, output, session) {
ns <- session$ns
txt <- reactive({
parentSession <- .subset2(session, "parent")
nodeVal <- input$tree_click$nodeValues[[1]]
if (is.null(nodeVal)) return(NULL)
return(paste(nodeVal, "is clicked"))
})
output$print <- renderText({
txt()
})
output$tree <- renderGrViz({
grViz("digraph test {A; B; A -> B;}")
})
return(txt)
}
ui <- fluidPage(
column(width=4, wellPanel("No module", verbatimTextOutput("print"), grVizOutput("tree"))),
column(width=4, wellPanel("Module 1", moduleUI("mod1"))),
column(width=4, wellPanel("Module 2", moduleUI("mod2")))
)
server <- function(input, output) {
mod1Val <- callModule(moduleController, "mod1")
observeEvent(mod1Val(), {
print(paste0("server[mod1]: ", mod1Val()))
})
mod2Val <- callModule(moduleController, "mod2")
observeEvent(mod2Val(), {
print(paste0("server[mod2]: ", mod2Val()))
})
txt <- reactive({
req(input$tree_click)
nodeval <- input$tree_click$nodeValues[[1]]
return(paste(nodeval, " is clicked"))
})
output$print <- renderPrint({
txt()
})
output$tree <- renderGrViz({
grViz("digraph test {A; B; A -> B;}")
})
}
shinyApp(ui = ui, server = server)

R Shiny: How can I return reactive values from a shiny module to the master server function?

I have a simple toy example that uses an add/removeBtn module to add and remove UI from "first" module. I need to keep track of the number of times add/remove has been clicked. If I do not use modules, it is easy, but I am trying to do this in the context of nested modules. Code is below, but basically, I cannot seem to get access to the return from the addRmBtnServer() in the main server function. I am sure it is a simple fix, but I have tried many ways around this, but cannot seem to get access to the result from my call to addRmBtnServer(). Thanks!
library(shiny)
firstUI <- function(id) { uiOutput(NS(id, "first")) }
firstServer <- function(input, output, session, a) {
output$first <- renderUI({
selectInput(session$ns("select"), h4("Select"), paste0(isolate(a()),letters[1:4]))
})
}
removeFirstUI <- function(id) {
removeUI(selector = paste0('#', NS(id, "first")))
}
addRmBtnUI <- function(id) {
ns <- NS(id)
tags$div(
actionButton(inputId = ns('insertParamBtn'), label = "Add"),
actionButton(ns('removeParamBtn'), label = "Remove"),
hr(),
tags$div(id = ns('placeholder'))
)
}
addRmBtnServer <- function(input, output, session, moduleToReplicate, ...) {
ns = session$ns
params <- reactiveValues(btn = 0)
observeEvent(input$insertParamBtn, {
params$btn <- params$btn + 1
callModule(moduleToReplicate$server, id = params$btn, ...)
insertUI(
selector = paste0('#', ns('placeholder')),
ui = moduleToReplicate$ui(ns(params$btn))
)
})
observeEvent(input$removeParamBtn, {
moduleToReplicate$remover(ns(params$btn))
params$btn <- params$btn - 1
})
return(params$btn)
}
ui <- fluidPage(
addRmBtnUI("addRm"),
textInput("a", label = "a", value = 1, width = '150px'),
verbatimTextOutput("view", placeholder = TRUE)
)
server <- function(input, output, session) {
pars <- callModule(
addRmBtnServer, id = "addRm",
moduleToReplicate = list(
ui = firstUI,
server = firstServer,
remover = removeFirstUI
),
)
output$view <- renderText({ pars() })
}
shinyApp(ui = ui, server = server)
As said in the comment, you can pass the values as return values in the corresponding server functions. There is a working example below. I left out the firstUI, firstServer and removeFirstUI implementations since they are irrelevant for your problem.
library(shiny)
addRmBtnUI <- function(id) {
ns <- NS(id)
tags$div(
actionButton(inputId = ns('insertParamBtn'), label = "Add"),
actionButton(ns('removeParamBtn'), label = "Remove"),
hr(),
tags$div(id = ns('placeholder'))
)
}
addRmBtnServer <- function(input, output, session, moduleToReplicate, ...) {
ns = session$ns
params <- reactiveValues(btn = 0)
observeEvent(input$insertParamBtn, {
params$btn <- params$btn + 1
callModule(moduleToReplicate$server, id = params$btn, ...)
insertUI(
selector = paste0('#', ns('placeholder')),
ui = moduleToReplicate$ui(ns(params$btn))
)
})
observeEvent(input$removeParamBtn, {
moduleToReplicate$remover(ns(params$btn))
params$btn <- params$btn - 1
})
return(reactive({params$btn}))
}
ui <- fluidPage(
addRmBtnUI("addRm"),
verbatimTextOutput("view", placeholder = TRUE)
)
server <- function(input, output, session) {
a <- reactive({input$a})
pars <- callModule(
addRmBtnServer, id = "addRm",
moduleToReplicate = list(
ui = function(...){},
server = function(...){},
remover = function(...){}
)
)
output$view <- renderText({ pars() })
}
shinyApp(ui = ui, server = server)

Resources