library(shiny)
library(ggplot2)

# module UI function
scatterOuput <- function(id){

  ns <- NS(id)

  tagList(

    br(),

    fluidRow(
      column(6,
         # dynamic controls to select x and y in plot1, to be rendered via server
         uiOutput(ns("dynamicControls")),

         # plot 1
         plotOutput(ns("plot1"))
      ),
      column(6,

         # dynamic controls to select x and y in plot2
         fluidRow(
           column(offset = 2, 4,
                  selectInput(ns("x2"),"x2",choices = names(mtcars), width = "100%")
           ),
           column(4,
                  selectInput(ns("y2"),"y2",choices = names(mtcars), width = "100%")
           )
         ),

         # plot 2
         plotOutput(ns("plot2"))
      )
    )
  )
}
# module server function
scatter <- function(input, output, session, data) {

  # set data
  data <- mtcars

  # dynamic controls
  output$dynamicControls <- renderUI({
    tagList(
      fluidRow(
        column(offset = 2, 4,
               selectInput("x1","x1",choices = names(mtcars), width = "100%")
        ),
        column(4,
               selectInput("y1","y1",choices = names(mtcars), width = "100%")
        )
      )
    )
  })

  # plot 1
  output$plot1 <- renderPlot({
    scatterPlot(data, c(input$x1,input$y1))
    #scatterPlot(data, c("mpg","disp"))
  })

  # plot2
  output$plot2 <- renderPlot({
    scatterPlot(data, c(input$x2,input$y2))
  })
}

# plot helper function
scatterPlot <- function(data, cols) {
  ggplot(data, aes_string(x = cols[1], y = cols[2])) + geom_point()
}

# main ui
ui <- fixedPage(
  scatterOuput("id1")
)

# main server
server <- function(input, output, session) {
  callModule(scatter, "id1", data = mtcars)
}

# run app
shinyApp(ui, server)