I am new to shinymodule and trying to modulize this reproducible shiny framework, with no success. I am trying to have 3 different modules, that communicate with each other. Here is the reproducible app without the modules.
library(shiny)
library(datasets)
ui <- shinyUI(fluidPage(
titlePanel("Column Plot"),
tabsetPanel(
tabPanel("Upload File",
titlePanel("Uploading Files"),
sidebarLayout(
sidebarPanel(
fileInput('file1', 'Choose CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
tags$br(),
checkboxInput('header', 'Header', TRUE),
radioButtons('sep', 'Separator',
c(Comma=',',
Semicolon=';',
Tab='\t'),
','),
radioButtons('quote', 'Quote',
c(None='',
'Double Quote'='"',
'Single Quote'="'"),
'"')
),
mainPanel(
tableOutput('contents')
)
)
),
tabPanel("First Tab",
pageWithSidebar(
headerPanel('My First Plot'),
sidebarPanel(
selectInput('xcol', 'X Variable', ""),
selectInput('ycol', 'Y Variable', "", selected = "")
),
mainPanel(
plotOutput('MyPlot')
)
)
),
tabPanel("second Tab",
sidebarLayout(
sidebarPanel(
fluidRow(
selectInput(
"disp",
"Display",
choices = c(
Summary = "summary",
Structure = "str",
dimension = "dimension"
),
selected = " "
)
)
),
mainPanel(
verbatimTextOutput("summaryy")
)
)
)
)
)
)
server <- shinyServer(function(input, output, session) {
data <- reactive({
req(input$file1)
inFile <- input$file1
df <- read.csv(inFile$datapath, header = input$header, sep = input$sep,
quote = input$quote)
updateSelectInput(session, inputId = 'xcol', label = 'X Variable',
choices = names(df), selected = names(df))
updateSelectInput(session, inputId = 'ycol', label = 'Y Variable',
choices = names(df), selected = names(df)[2])
return(df)
})
output$contents <- renderTable({
data()
})
output$MyPlot <- renderPlot({
x <- data()[, c(input$xcol, input$ycol)]
plot(x)
})
output$summaryy <- renderPrint({
if (input$disp == "summary"){
return(summary(data()))
} else if (input$disp == "str"){
return(str(data()))
} else if (input$disp == "dimension"){
return(dim(data()))
}
else{
return()
}
})
})
shinyApp(ui, server)
And here is my attempt at modulizing the app, with three different modules, with no success. What should I do so that the modules communicate with each other and also regarding the updateselectInput() function, since, I will have more tabset/other modules that will be dependent to the uploaded data and its variables.
data_upload_Ui <- function(id){
ns <- NS(id)
tabPanel("Upload File",
titlePanel("Uploading Files"),
sidebarLayout(
sidebarPanel(
fileInput(ns('file1'), 'Choose CSV File',
accept=c('text/csv',
'text/comma-separated-values,text/plain',
'.csv')),
tags$br(),
checkboxInput(ns('header'), 'Header', TRUE),
radioButtons(ns('sep'), 'Separator',
c(Comma=',',
Semicolon=';',
Tab='\t'),
','),
radioButtons(ns('quote'), 'Quote',
c(None='',
'Double Quote'='"',
'Single Quote'="'"),
'"')
),
mainPanel(
tableOutput(ns('contents'))
)
)
)
}
data_upload_Server <- function(id){
moduleServer(id, function(input, output, session){
data <- reactive({
req(input$file1)
inFile <- input$file1
df <- read.csv(inFile$datapath, header = input$header, sep = input$sep,
quote = input$quote)
updateSelectInput(session, inputId = 'xcol', label = 'X Variable',
choices = names(df), selected = names(df))
updateSelectInput(session, inputId = 'ycol', label = 'Y Variable',
choices = names(df), selected = names(df)[2])
return(df)
})
output$contents <- renderTable({
data()
})
}
)
}
#########################
plot_UI <- function(id){
ns <- NS(id)
tabPanel("First Tab",
pageWithSidebar(
headerPanel('My First Plot'),
sidebarPanel(
# "Empty inputs" - they will be updated after the data is uploaded
selectInput(ns('xcol'), 'X Variable', ""),
selectInput(ns('ycol'), 'Y Variable', "", selected = "")
),
mainPanel(
plotOutput(ns('MyPlot'))
)
)
)
}
plot_Server <- function(id){
moduleServer(id, function(input, output, session){
output$MyPlot <- renderPlot({
x <- data()[, c(input$xcol, input$ycol)]
plot(x)
})
}
)
}
###############################################
info_Ui <- function(id){
ns <- NS(id)
tabPanel("second Tab",
sidebarLayout(
sidebarPanel(
fluidRow(
selectInput(ns(
"disp"),
"Display",
choices = c(
Summary = "summary",
Structure = "str",
dimension = "dimension"
),
selected = " "
)
)
),
mainPanel(
verbatimTextOutput(ns("summaryy"))
)
)
)
}
info_Server <- function(id){
moduleServer(id, function(input, output, session){
output$summaryy <- renderPrint({
if (input$disp == "summary"){
return(summary(data()))
} else if (input$disp == "str"){
return(str(data()))
} else if (input$disp == "dimension"){
return(dim(data()))
}
else{
return()
}
})
}
)
}
I wrote this simple function to run the modules, but only the first modules is working. Grateful for all the help.
####################################
run_App <- function(){
ui <- shinyUI(fluidPage(
titlePanel("Column Plot"),
tabsetPanel(
data_upload_Ui("data"),
plot_UI("plot_1"),
info_Ui("info")
)
)
)
server <- function(input, output, session){
data_upload_Server("data")
plot_Server("plot_1")
info_Server("info")
}
shinyApp(ui, server)
}
run_App()