Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R shiny: How to build dynamic UI (text input)

Tags:

r

textinput

shiny

I'm trying to build dynamic textInput with R shiny. The user should write in a text field then push an add button to fill another field. However, each time I push the button all the fields become empty, It's like if I must define how many fields I want in advance. Any help will be very appreciated.

Thank you

Here is my code:

library(shiny)

shiny::runApp(list(
ui = pageWithSidebar(
headerPanel("test"),
sidebarPanel(
  helpText("Alternatives list"),
  verbatimTextOutput("summary")
),    
mainPanel(  
  actionButton("obs","add"),
  htmlOutput("selectInputs")     
)  
)
, 

server = function(input,output){
observe({

  if (input$obs == 0) 
    return()
  isolate({

    output$selectInputs <- renderUI({
      if(!is.null(input$obs))  
        print("w")
      w <- ""
      for(i in 1:input$obs) {
        w <- paste(w,textInput(paste("a",i,sep=""),paste("a",i,sep="")))
      }
      HTML(w)
    })
    output$summary <- renderPrint({  
      print("your Alternative are:")

      for(i in 1:input$obs) {
        print(              
          input[[sprintf("a%d",i)]]
        )
      }
    })
    outputOptions(output, 'selectInputs', suspendWhenHidden=FALSE)
  })
})
}))
like image 638
user1431694 Avatar asked Mar 04 '14 00:03

user1431694


People also ask

In Which method do we write the code to make changes to UI dynamically?

setLayoutParams(new LayoutParams(LayoutParams. MATCH_PARENT, LayoutParams. WRAP_CONTENT)); ll. addView(btn);

How do I render a Shiny text in R?

Use renderText in server to tell Shiny how to build the text. You'll need to use the same name to refer to the text in both scripts (e.g., "min_max" ). Your text should use both the slider's min value (saved as input$range[1] ) and its max value (saved as input$range[2] ).

How do you make a UI Shiny?

You lay out the user interface of your app by placing elements in the fluidPage function. For example, the ui function below creates a user interface that has a title panel and a sidebar layout, which includes a sidebar panel and a main panel. Note that these elements are placed within the fluidPage function.

How do you show a message in Shiny?

Simply call shinyalert() with the desired arguments, such as a title and text, and a modal will show up. In order to be able to call shinyalert() in a Shiny app, you must first call useShinyalert() anywhere in the app's UI.


1 Answers

Your problem is that you regenerate all the buttons (so the input$aX) each time you click on the button. And they are generated without value by default, that's why when you read them they are all nulls.

For example you can see your mistake if you supress the loop in your output$selectInputs code : (But now it only allow you to set each aX only 1 time.)

    output$selectInputs <- renderUI({
      if(!is.null(input$obs))
        print("w")
      w <- ""
      w <- paste(w, textInput(paste("a", input$obs, sep = ""), paste("a", input$obs, sep = "")))
      HTML(w)
    })

Keeping your code (then keeping the regeneration of all the buttons), you should add to the value argument of each textInput his "own value" (in reality, the value of the old input with the same id) value = input[[sprintf("a%d",i)]] :

    output$selectInputs <- renderUI({
      w <- ""
      for(i in 1:input$obs) {
        w <- paste(w, textInput(paste("a", i, sep = ""), paste("a", i, sep = ""), value = input[[sprintf("a%d",i)]]))
      }
      HTML(w)
    })
like image 196
Julien Navarre Avatar answered Oct 05 '22 07:10

Julien Navarre