Re: How to dynamically add modules

401 views
Skip to first unread message
Message has been deleted

MySchizo Buddy

unread,
Mar 17, 2016, 5:15:09 PM3/17/16
to Shiny - Web Framework for R



This isn't about creating modules using renderUI.
With renderUI as i understand it you put a placeholder inside the UI function and then you write your controls/widget inside the server function.

Modules come in two parts. One part you have to add to the UI function and another part to the server function using callModule().

I have a slider module. I want to add it to a wellpanel when an "add" action button is clicked. If it helps you can think of duplicating the module as many times i want when a button is clicked. The duplicate modules should all be independent.

Visually

I want to know how can an action button add the UI part of the module inside the UI function and server part inside the server function.

#Dynamically adding modules
library
(shiny)

#slider module ------------------------
sliderUI
<- function(id) {
  ns
<- NS(id)
  sliderInput
(ns("bins"), "Number of Bins:", min = 1, max = 5, value = 3)
}

slider
<- function(input, output, session) {}


#shiny app ------------------------
ui
<- fixedPage(
  fixedRow
(
    column
(width = 4, wellPanel(
      h4
("Slider Module"),
      sliderUI
("slider"),
      actionButton
("addSliderModule", "Add Slider Module"))
   
),
    column
(width = 4, wellPanel(
      h4
("Dynamic Loading Modules"),
      p
("Clicking on the 'Add' button on the left should add the module here. You should be able to duplicate that slider module as many times as the button is clicked"),
      hr
())
   
)
 
)
)

server
<- function(input, output, session) {
  observeEvent
(input$addSliderModule, {
   
#what goes here
 
})
}

shinyApp
(ui, server)


   
  [2]: https://groups.google.com/forum/#!topic/shiny-discuss/BMZR3_MH0S4

MySchizo Buddy

unread,
Mar 18, 2016, 11:12:13 AM3/18/16
to Shiny - Web Framework for R
A solution is posted on stackoverflow
It's a very complicated solution Where most of the work is done in javascript. But it does work as expected.

MySchizo Buddy

unread,
Mar 28, 2016, 10:19:44 AM3/28/16
to Shiny - Web Framework for R
OK I have a partial solution that duplicates the module only once. Looks like you have to manually create x uiOutput placeholder to duplicate the module x times.

here is the code to duplicate it once.

#Dynamically adding modules
    library
(shiny)
   
   
#slider module ------------------------
    sliderUI
<- function(id) {
      ns
<- NS(id)

      tagList
(
        sliderInput
(ns("bins"), "Number of Bins:", min = 1, max = 5, value = 3),
        textOutput
(ns("textBins"))  
     
)

   
}
   
    slider
<- function(input, output, session) {

      output$textBins
<- renderText({
        input$bins
     
})

   
}
   
   
   
#shiny app ------------------------
    ui
<- fixedPage(
      fixedRow
(
        column
(width = 4, wellPanel(
          h4
("Slider Module"),

          sliderUI
("originalSlider"),

          actionButton
("addSliderModule", "Add Slider Module"))
       
),
        column
(width = 4, wellPanel(
          h4
("Dynamic Loading Modules"),
         
 p
("Clicking on the 'Add' button on the left should add the module here.
 You should be able to duplicate that slider module as many times as the
 button is clicked"
),

          hr
(),
          uiOutput
("addModule"))

       
)
     
)
   
)
   
    server
<- function(input, output, session) {

     
#server code for the original module
      callModule
(slider, "originalSlider")
     
     
#Here we add the UI and callModule of the duplicate module
      observeEvent
(input$addSliderModule, {
        duplicateSliderid
<- paste0("duplicateSlider", input$addSliderModule)
       
        output$addModule
<- renderUI({
          sliderUI
(duplicateSliderid)
       
})
        callModule
(slider, duplicateSliderid)
       
     
})
   
}
   
    shinyApp
(ui, server)


Joe Cheng

unread,
Mar 28, 2016, 12:24:20 PM3/28/16
to MySchizo Buddy, Shiny - Web Framework for R
Sorry for not replying sooner. This is one idea:

Basically your observeEvent will help build up a list of sliderUI, and callModule(slider). And the renderUI will just display the list.

I just realized, I think you're going to find this slightly problematic at some point because adding a slider will reset all the other sliders to default values. You can fix this by changing the list of sliderUI to a list of slider id's. Then the renderUI should be modified to take the list of slider id's, and return a sliderUI with the default value set to input$duplicateSliderX if that value exists.

Sorry, this is much more difficult than it needs to be. We're talking about adding an "appendUI" type of function to Shiny itself.

--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/287191a7-e6d5-43e1-bf24-56c8b9a6d75a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

MySchizo Buddy

unread,
Mar 28, 2016, 1:50:00 PM3/28/16
to Shiny - Web Framework for R, myschi...@gmail.com
Thank you Joe.
Please make appendUI. you have here a very real use case for appendUI. Hopefully the core devs will see the benefits of this function.
I'll keep an eye on github shiny repo.
Reply all
Reply to author
Forward
0 new messages