RShiny: получение селекторов jsQuery для элементов пользовательского интерфейса в tabsetPanel, которые имеют случайно сгенерированные идентификаторы - PullRequest
1 голос
/ 16 января 2020

Я пытаюсь создать форму в панели управления rShiny, которая позволит пользователю добавлять строки с помощью insertUI. Для правильной работы функции insertUI необходим селектор jQuery последней строки формы. Это позволяет insertUI знать, где разместить новую строку.

Проблема, с которой я сталкиваюсь: поскольку эта форма обернута в tabPanel, селектор jQuery, необходимый для ссылки на каждую строку, выглядит рандомизированным. Каждый раз, когда приложение загружается, идентификатор, используемый для ссылки на панель вкладок, отображается как «tab-XXXX-1» с четырьмя случайными цифрами вместо XXXX. Я использовал «Инспектировать элемент» в Chrome, чтобы убедиться в этом сам.

Есть ли способ заставить панель вкладок просто придерживаться одного идентификатора, который я ему даю? Код для воссоздания этого ниже. Любая помощь очень ценится!

# 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)

1 Ответ

0 голосов
/ 16 января 2020

Когда вы создаете tabPanel, оберните строки входных данных в div, но исключите кнопку и присвойте div идентификатор. В моем примере ниже я назвал его "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)))
      )
    )
  })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...