根据之前的小部件的选择显示动态生成的"selectizeInput"小部件的选择 [英] Display the selected choice of a dynamically generated 'selectizeInput' widget based on the selected choice of previous widget

查看:68
本文介绍了根据之前的小部件的选择显示动态生成的"selectizeInput"小部件的选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个Shiny应用程序,该应用程序在用户按下"+"按钮时生成带有多个selectInput或selectizeInput小部件的行,并在他按下-"按钮时删除此类行.下图显示了我从现在开始所取得的成就:

I am trying to build a Shiny app that generates rows with multiple selectInput or selectizeInput widgets when a user presses the "+" button, and that removes such rows when he presses the "-" button. The image below show what I have achieved since now:

我的闪亮应用现在的外观: https://imgur.com/uQfdJrv

How my shiny app looks right now: https://imgur.com/uQfdJrv

我的问题是我找不到一种在新行中显示具有与上一行中的小部件相同的选定值的小部件的方法.实际上,用户可能只想更改某些输入的值,而不想更改其他输入的值.

My problem is that I can't find a way to show the widgets in the new row with the same selected values of the widget in the previous row. In fact, the user may want to change just values of some inputs and don't touch the values of the others.

参考上图,我们假设用户在第一次测试中选择了"Amikacin"作为抗生素,选择了"5"作为AMR.第二个测试始终使用"Amikacin",但他的AMR值为10.在按下"+"按钮后,新输入必须立即显示"Amikacin"和"5",然后用户将进行更改"10"中第二行的"5".

Referring to the image above, let's suppose that for the first test an user has selected "Amikacin" as antibiotics and "5" as AMR. The second test is always with "Amikacin" but he got the AMR value of 10. The new inputs, right after pressing the "+" button, must display immediately "Amikacin" and "5", and after that the user will just change the "5" of the second row in a "10".

这是我使用的代码:


library(shiny)
library(shinyjs)

###= UI
ui <- fluidPage(

br(),

useShinyjs(),

  fluidRow(
    column(width = 12,
           actionButton(inputId = "add_amr_test",
                        label = icon(name = "plus",
                                     lib = "font-awesome")),
           actionButton(inputId = "remove_amr_test",
                        label = icon(name = "minus",
                                     lib = "font-awesome")),
           div(style = "display: inline-block;
                        padding: 0px 10px;",
               h5("Add or remove an antimicrobial resistance test")),
           tags$div(id = "amr_test_placeholder")
    )
  ),

br()

)

###= SERVER
server <- function(input, output, session) {

  Antibiotics_name <- c("", "Amikacin", "Ampicillin", "Tetracycline")

  observe({

    toggleState(id = "remove_amr_test",
                condition = input$add_amr_test > input$remove_amr_test)

  })

  amr_test_values <- reactiveValues(val = 0)

  ###= Add ui
  observeEvent(input$add_amr_test, {

    amr_test_divId <- length(amr_test_values$val) + 1

    insertUI(
      selector = "#amr_test_placeholder",
      where = "beforeBegin",
      ui = tags$div(
        id = amr_test_divId,
        fluidRow(

          br(),

          column(width = 3,
                 selectizeInput(inputId = paste0("drug_",
                                                 input$add_amr_test - input$remove_amr_test),
                                label = h5(paste0("Antibiotic ",
                                                  input$add_amr_test - input$remove_amr_test)),
                                choices = Antibiotics_name,
                                selected = "")
          ),
          column(width = 1,
                 selectizeInput(inputId = paste0("rescom_",
                                                 input$add_amr_test - input$remove_amr_test),
                                label = h5(paste0("AMR ",
                                                  input$add_amr_test - input$remove_amr_test)),
                                choices = c("",
                                            seq(from = 1,
                                                to = 100,
                                                by = 1)),
                                selected = "")
          )
        )
      )
    )

    amr_test_values$val <- c(amr_test_values$val,
                             amr_test_divId)

  })

  ###= Remove ui
  observeEvent(input$remove_amr_test, {

    removeUI(

      selector = paste0('#', amr_test_values$val[length(amr_test_values$val)])

    )

    amr_test_values$val <- amr_test_values$val[-length(amr_test_values$val)]

  })

}



###= RUN APP
shinyApp(ui = ui, server = server)

最后,这是一张带有用户按下"+"按钮生成第二行小部件后获得的预期结果的图像.

Finally, here is an image with the expected results obtained after the user presses the "+" button to generate the second row of widgets.

预期结果示例: https://imgur.com/NIpOZOE

最后一个问题:用户的每个小部件都有一个特定值后,这是将所有这些值存储在数据框中的最佳方法吗?

One last question: once every widget from the user has a specific value, which is the best way to store all these values inside a dataframe?

非常感谢.

推荐答案

第一个问题请参见以下内容:

Please see below for your first question:

library(shiny)
library(shinyjs)

###= UI
ui <- fluidPage(

br(),

useShinyjs(),

  fluidRow(
    column(width = 12,
           actionButton(inputId = "add_amr_test",
                        label = icon(name = "plus",
                                     lib = "font-awesome")),
           actionButton(inputId = "remove_amr_test",
                        label = icon(name = "minus",
                                     lib = "font-awesome")),
           div(style = "display: inline-block;
                        padding: 0px 10px;",
               h5("Add or remove an antimicrobial resistance test")),
           tags$div(id = "amr_test_placeholder")
    )
  ),

br()

)

###= SERVER
server <- function(input, output, session) {

  Antibiotics_name <- c("", "Amikacin", "Ampicillin", "Tetracycline")

  observe({

    toggleState(id = "remove_amr_test",
                condition = input$add_amr_test > input$remove_amr_test)

  })

  amr_test_values <- reactiveValues(val = 0)

  ###= Add ui
  observeEvent(input$add_amr_test, {

    amr_test_divId <- length(amr_test_values$val) + 1

    # Simplified input_number here and code to obtain previous values if they exist
    input_number <- input$add_amr_test - input$remove_amr_test
    if (!is.null(eval(parse(text = paste0("input$drug_", input_number - 1))))) {
        drug_value = eval(parse(text = paste0("input$drug_", input_number - 1)))
    } else {
        drug_value = ""
    }
    if (!is.null(eval(parse(text = paste0("input$rescom_", input_number - 1))))) {
        rescom_value = eval(parse(text = paste0("input$rescom_", input_number - 1)))
    } else {
        rescom_value = ""
    }

    insertUI(
      selector = "#amr_test_placeholder",
      where = "beforeBegin",
      ui = tags$div(
        id = amr_test_divId,
        fluidRow(

          br(),

          column(width = 3,
                 selectizeInput(inputId = paste0("drug_",
                                                 input_number),
                                label = h5(paste0("Antibiotic ",
                                                  input_number)),
                                choices = Antibiotics_name,
                                selected = drug_value)
          ),
          column(width = 1,
                 selectizeInput(inputId = paste0("rescom_",
                                                 input_number),
                                label = h5(paste0("AMR ",
                                                  input_number)),
                                choices = c("",
                                            seq(from = 1,
                                                to = 100,
                                                by = 1)),
                                selected = rescom_value)
          )
        )
      )
    )

    amr_test_values$val <- c(amr_test_values$val,
                             amr_test_divId)

  })

  ###= Remove ui
  observeEvent(input$remove_amr_test, {

    removeUI(

      selector = paste0('#', amr_test_values$val[length(amr_test_values$val)])

    )

    amr_test_values$val <- amr_test_values$val[-length(amr_test_values$val)]

  })

}



###= RUN APP
shinyApp(ui = ui, server = server)

这篇关于根据之前的小部件的选择显示动态生成的"selectizeInput"小部件的选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆