Shiny 中的动态小部件

huangapple go评论54阅读模式
英文:

Dynamic widgets in shiny

问题

我有一个示例应用程序如下。 创意是默认情况下只能看到2个小部件。 但是当单击“添加”时,小部件会继续添加。 但是当我们第一次单击“添加”时,小部件会弹出(这没问题),现在当在“第一家公司”中输入一些值,然后单击“添加”,另一个小部件会弹出(这也没问题)。 但是现在,“第一家公司”的值消失了。 我们可以在单击“添加”时使其出现吗?

library(shiny)

ui <- fluidPage(
  uiOutput("fcompany"),
  uiOutput("add_exp"),
  actionButton("add_button", "Add")
)

server <- function(input, output, session) {
  
  get_data <- reactiveValues()
  
  get_data$all_experiences <- c(0) 
  
  output$fcompany <- renderUI({
    column(width = 2, textInput("id_zero", label = "Gra", placeholder = "Col"), 
           numericInput("idexp_zero", label = "", value = 4, min = 0, max = 10))
  })
  
  
  observeEvent(input$add_button,{
    
    added_variable <- max(get_data$all_experiences)+1
    
    excel_Input <- structure(list(number = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), words = c("one", 
                                                                                       "two", "three", "four", "five", "six", "seven", "eight", "nine", 
                                                                                       "ten"), company = c("First Company", "Second Company", "Third Company", 
                                                                                                           "Fourth Company", "Fifth Company", "Sixth Company", "Seventh Company", 
                                                                                                           "Eighth Company", "Ninth Company", "Tenth Company")), row.names = c(NA, 
                                                                                                                                                                               10L), class = "data.frame")
    output$add_exp <- renderUI({
      lapply(1:added_variable, function(i){
        column(width = 2, textInput(paste0("id_",excel_Input$words[excel_Input$number == i]), label = excel_Input$company[excel_Input$number == i], 
                                    placeholder = paste0("Enter the ", excel_Input$company[excel_Input$number == i])), 
               numericInput(paste0("idexp_",excel_Input$words[excel_Input$number == i]), label = "", value = 4, min = 0, max = 10))
      })
    })
    
    get_data$all_experiences <- c(get_data$all_experiences, added_variable)
    
  })
  
}

shinyApp(ui, server)
英文:

I have a sample application as below. The idea is only 2 widgets are seen by default. But when you click on "Add", the widgets keep on adding. But when we click "Add" for the first time, the widgets pops up (that is fine) and now when enter some value in "First Company" and then click on "Add", another widgets pops up(this is also fine). But now, the values in "First Company" disappears. Can we make is appear when we click on "Add"

library(shiny)

ui &lt;- fluidPage(
  uiOutput(&quot;fcompany&quot;),
  uiOutput(&quot;add_exp&quot;),
  actionButton(&quot;add_button&quot;, &quot;Add&quot;)
)

server &lt;- function(input, output, session) {
  
  get_data &lt;- reactiveValues()
  
  get_data$all_experiences &lt;- c(0) 
  
  output$fcompany &lt;- renderUI({
    column(width = 2, textInput(&quot;id_zero&quot;, label = &quot;Gra&quot;, placeholder = &quot;Col&quot;), 
           numericInput(&quot;idexp_zero&quot;, label = &quot;&quot;, value = 4, min = 0, max = 10))
  })
  
  
  observeEvent(input$add_button,{
    
    added_varaible &lt;- max(get_data$all_experiences)+1
    
    excel_Input &lt;- structure(list(number = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), words = c(&quot;one&quot;, 
                                                                                       &quot;two&quot;, &quot;three&quot;, &quot;four&quot;, &quot;five&quot;, &quot;six&quot;, &quot;seven&quot;, &quot;eight&quot;, &quot;nine&quot;, 
                                                                                       &quot;ten&quot;), company = c(&quot;First Company&quot;, &quot;Second Company&quot;, &quot;Third Company&quot;, 
                                                                                                           &quot;Fourth Company&quot;, &quot;Fifth Company&quot;, &quot;Sixth Company&quot;, &quot;Seventh Company&quot;, 
                                                                                                           &quot;Eighth Company&quot;, &quot;Ninth Company&quot;, &quot;Tenth Company&quot;)), row.names = c(NA, 
                                                                                                                                                                               10L), class = &quot;data.frame&quot;)
    output$add_exp &lt;- renderUI({
      lapply(1:added_varaible, function(i){
        column(width = 2, textInput(paste0(&quot;id_&quot;,excel_Input$words[excel_Input$number == i]), label = excel_Input$company[excel_Input$number == i], 
                                    placeholder = paste0(&quot;Enter the &quot;, excel_Input$company[excel_Input$number == i])), 
               numericInput(paste0(&quot;idexp_&quot;,excel_Input$words[excel_Input$number == i]), label = &quot;&quot;, value = 4, min = 0, max = 10))
      })
    })
    
    get_data$all_experiences &lt;- c(get_data$all_experiences, added_varaible)
    
  })
  
}

shinyApp(ui, server)

答案1

得分: 1

以下是代码的翻译部分:

你没有提供有关应用程序更广泛目标的多少上下文。
我建议预定义所有需要的扩展输入,并默认隐藏它们。稍后,如果需要,我们可以取消隐藏每个输入。

library(shiny)

excel_Input <- structure(
  list(
    number = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
    words = c("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"),
    company = c(
      "First Company", "Second Company", "Third Company",
      "Fourth Company", "Fifth Company", "Sixth Company", "Seventh Company",
      "Eighth Company", "Ninth Company", "Tenth Company"
    )
  ),
  row.names = c(NA, 10L),
  class = "data.frame"
)

ex_inputs <- append(
  list(shiny::tags$div(
    shiny::textInput("id_zero", label = "Gra", placeholder = "Col"),
    shiny::numericInput("idexp_zero", label = "", value = 4, min = 0, max = 10)
  )),
  lapply(
    seq_len(nrow(excel_Input)),
    function(i) {
      ex_word <- excel_Input$words[excel_Input$number == i]
      ex_label <- excel_Input$company[excel_Input$number == i]
      ex_company <- excel_Input$company[excel_Input$number == i]
      shiny::tags$div(
        id = sprintf("ex_%s", i),
        class = "hidden",
        shiny::textInput(
          paste0("id_", ex_word),
          label = ex_label,
          placeholder = paste0("输入", ex_company)
        ),
        shiny::numericInput(paste0("idexp_", ex_word), label = ex_word, value = 4, min = 0, max = 10)
      )
    }
  )
)

ui <- fluidPage(
  shinyjs::useShinyjs(),
  shiny::tags$div(
    shiny::tags$div(
      style = "display: flex",
      ex_inputs
    ),
    shiny::tags$div(
      actionButton("add_button", "添加")
    )
  )
)

server <- function(input, output, session) {
  counter <- shiny::reactiveVal(0)
  shiny::observeEvent(input$add_button, {
    if (counter() < 10) counter(counter() + 1)
  })
  shiny::observe(shinyjs::removeClass(sprintf("ex_%s", counter()), "hidden"))
  
  # 测试
  observe({
    lapply(seq_len(counter()), function(i) {
      ex_word <- excel_Input$words[excel_Input$number == i]
      print(input[[paste0("id_", ex_word)]])
    })
  })
}

shiny::shinyApp(ui, server)
英文:

You did not provide much context about the broader objective of the app.
I propose to pre-define all needed extension inputs and hide them by default. Later we can unhide each if needed.

library(shiny)

excel_Input &lt;- structure(
  list(
    number = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
    words = c(&quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;, &quot;five&quot;, &quot;six&quot;, &quot;seven&quot;, &quot;eight&quot;, &quot;nine&quot;, &quot;ten&quot;),
    company = c(
      &quot;First Company&quot;, &quot;Second Company&quot;, &quot;Third Company&quot;,
      &quot;Fourth Company&quot;, &quot;Fifth Company&quot;, &quot;Sixth Company&quot;, &quot;Seventh Company&quot;,
      &quot;Eighth Company&quot;, &quot;Ninth Company&quot;, &quot;Tenth Company&quot;
    )
  ),
  row.names = c(NA, 10L),
  class = &quot;data.frame&quot;
)

ex_inputs &lt;- append(
  list(shiny::tags$div(
    shiny::textInput(&quot;id_zero&quot;, label = &quot;Gra&quot;, placeholder = &quot;Col&quot;),
    shiny::numericInput(&quot;idexp_zero&quot;, label = &quot;&quot;, value = 4, min = 0, max = 10)
  )),
  lapply(
    seq_len(nrow(excel_Input)),
    function(i) {
      ex_word &lt;- excel_Input$words[excel_Input$number == i]
      ex_label &lt;- excel_Input$company[excel_Input$number == i]
      ex_company &lt;- excel_Input$company[excel_Input$number == i]
      shiny::tags$div(
        id = sprintf(&quot;ex_%s&quot;, i),
        class = &quot;hidden&quot;,
        shiny::textInput(
          paste0(&quot;id_&quot;, ex_word),
          label = ex_label,
          placeholder = paste0(&quot;Enter the &quot;, ex_company)
        ),
        shiny::numericInput(paste0(&quot;idexp_&quot;, ex_word), label = ex_word, value = 4, min = 0, max = 10)
      )
    }
  )
)

ui &lt;- fluidPage(
  shinyjs::useShinyjs(),
  shiny::tags$div(
    shiny::tags$div(
      style = &quot;display: flex&quot;,
      ex_inputs
    ),
    shiny::tags$div(
      actionButton(&quot;add_button&quot;, &quot;Add&quot;)
    )
  )
)

server &lt;- function(input, output, session) {
  counter &lt;- shiny::reactiveVal(0)
  shiny::observeEvent(input$add_button, {
    if (counter() &lt; 10) counter(counter() + 1)
  })
  shiny::observe(shinyjs::removeClass(sprintf(&quot;ex_%s&quot;, counter()), &quot;hidden&quot;))
  
  # Test
  observe({
    lapply(seq_len(counter()), function(i) {
      ex_word &lt;- excel_Input$words[excel_Input$number == i]
      print(input[[paste0(&quot;id_&quot;, ex_word)]])
    })
  })
}

shiny::shinyApp(ui, server)

huangapple
  • 本文由 发表于 2023年3月12日 11:43:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710943.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定