RShiny:检索 tabsetPanel 中具有随机生成 ID 的 UI 项的 jsQuery 选择器



我正在尝试在rShiny仪表板中创建一个表单,该表单将允许用户使用insertUI添加行。为了使 insertUI 函数正常工作,它需要表单最后一行的 jQuery 选择器。这让 insertUI 知道放置新行的位置。

我遇到的问题是:由于此表单包装在tabPanel中,因此引用每一行所需的jQuery选择器似乎是随机的。每次加载应用时,用于引用选项卡窗格的 ID 都显示为"tab-XXXX-1",用四个随机数字代替 XXXX。我在Chrome中使用了"检查元素"来亲自查看。

有没有办法强制选项卡面板只坚持使用我给它的一个 ID?重新创建此内容的代码如下。非常感谢任何和所有的帮助!

# Libraries---
library(shiny)
library(shinydashboard)
library(tidyverse)
library(shinyWidgets)
library(shinyjs)
library(Cairo)
library(plotly)
library(purrr)
library(zoo)
library(DT)
library(magrittr)
#ui------
ui_body_BDay <- tabPanel("Birthday inputs",
value ="BDay_inputs",
fluidRow(
column(3, textInput(inputId = paste0("name", 1), 
label = paste0("Name ", 1))),
column(3, dateInput(inputId = paste0("b-day", 1) , 
label = paste0("Birthday", 1)))
),
fluidRow(
column(3, textInput(inputId = paste0("name", 2), 
label = paste0("Name ", 2))),
column(3, dateInput(inputId = paste0("b-day", 2) , 
label = paste0("Birthday", 2)))
),
#button to add rows
fluidRow(
column(9, actionButton("add", "Add row"))
)
)
ui_dashboardBody <- dashboardBody(
tabItems(
tabItem(
tabName = "tab_BDay",
tabBox(title = "", width = 12,
id = "BDay_tabset",
ui_body_BDay)
)
)
)
ui_sidebar_item <- dashboardSidebar(
menuItem(
text = "Birthday Collection",
tabName = "tab_BDay",
icon = icon("wrench", lib = "font-awesome")
)
)
ui <- dashboardPage(
header = dashboardHeader(title = "Birthday example"),
sidebar = ui_sidebar_item,
body = ui_dashboardBody
)
#server-----
server <- function(input, output, session){
DefRows <- 2 #initialize with default number of rows, 2
values <- reactiveValues(NumRows = DefRows)
#Code for adding rows when button is clicked ---
observeEvent(input$add, {
values$NumRows <- values$NumRows + 1
insertUI(
#This is the problematic line: the id for the tabPanel object, tab-XXXX-1, changes every time the app loads
selector = paste0("#tab-9719-1 > div:nth-child(", values$NumRows-1, ") > div:nth-child(1)"),
where = c("afterEnd"),
fluidRow(
column(3, textInput(inputId = paste0("name", values$NumRows), 
label = paste0("Name ", values$NumRows))),
column(3, dateInput(inputId = paste0("b-day", values$NumRows) , 
label = paste0("Birthday ", values$NumRows)))
)
)
})
}
shinyApp(ui, server)

创建tabPanel时,将输入行包装在div中,但排除按钮,并为div 提供一个 ID。在下面的例子中,我称之为"bday_input_rows"。

ui_body_BDay <- tabPanel(
"Birthday inputs",
value = "BDay_inputs",
tags$div(id = "bday_input_rows",
fluidRow(
column(3, textInput(
inputId = paste0("name", 1),
label = paste0("Name ", 1)
)),
column(3, dateInput(
inputId = paste0("b-day", 1) ,
label = paste0("Birthday", 1)
))
),
fluidRow(
column(3, textInput(
inputId = paste0("name", 2),
label = paste0("Name ", 2)
)),
column(3, dateInput(
inputId = paste0("b-day", 2) ,
label = paste0("Birthday", 2)
))
)),
#button to add rows
fluidRow(column(9, actionButton("add", "Add row")))
)

然后,您可以将选择器指定为selector = "#bday_input_rows"

server <- function(input, output, session){
DefRows <- 2 #initialize with default number of rows, 2
values <- reactiveValues(NumRows = DefRows)
#Code for adding rows when button is clicked ---
observeEvent(input$add, {
values$NumRows <- values$NumRows + 1
insertUI(
#This is the problematic line: the id for the tabPanel object, tab-XXXX-1, changes every time the app loads
selector = "#bday_input_rows",
where = c("beforeEnd"),
fluidRow(
column(3, textInput(inputId = paste0("name", values$NumRows), 
label = paste0("Name ", values$NumRows))),
column(3, dateInput(inputId = paste0("b-day", values$NumRows) , 
label = paste0("Birthday ", values$NumRows)))
)
)
})
}

最新更新