У меня есть блестящее приложение, которое генерирует варианты для selectizeInput()
на основе значения другого селектора. В частности, он находит уникальные значения выбранной переменной и затем делает этот выбор. Я инициализирую селектор с помощью selectizeInput()
в пользовательском интерфейсе, а затем использую observe({})
, чтобы определить изменения во входных данных, а затем вызываю updateSelectizeInput()
, чтобы изменить выбор. Все это работает нормально.
Проблема, с которой я сталкиваюсь, заключается в том, что когда я использую rintrojs
, селектор вариантов определяется через приложение в первый раз, но когда варианты выбора обновляются, если я попытаюсь вернуться к ним снова, элемент не может быть найден. Вот несколько скриншотов, которые идентифицируют проблему. Во-первых, вот скриншот первого шага урока:
Далее я могу выбрать два значения в селекторе групп сравнения.
Затем он отправляет меня обратно, чтобы выбрать другое значение для группы 1, я выбираю «y».
Наконец, когда руководство пытается вернуться к группам сравнения, оно просто перемещает всплывающую подсказку в верхний левый угол.
Но с обновлением селектора проблем не возникло: вы можете видеть, что теперь он имеет значения D, E и F.
Есть ли у вас идеи, почему я не могу вернуться к средству выбора групп сравнения после обновления вариантов. Как видно из кода ниже, я использую тот же идентификатор для выбора селектора группы сравнения, который работает в первый раз, но не во второй. Вот игрушечный пример.
library(shiny)
library(rintrojs)
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("IntroJS Problem"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
actionButton("browser", "browser"),
introjsUI(),
actionButton("btn","Interactive Tutorial"),
selectizeInput("grp1",
"Grouping Variable",
choices = c("x", "y"),
selected = "x"),
selectizeInput("compgroup", "Compare Groups (Choose 2)", choices = "", multiple=TRUE, options=list(maxItems=2))
),
# Show a plot of the generated distribution
mainPanel(
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
library(rintrojs)
observeEvent(input$browser,{
browser()
})
observe({
g1 <- input$grp1
if (g1 == "x"){
chc <- c("A", "B", "C")
}
if (g1 == "y"){
chc <- c("D", "E", "F")
}
updateSelectizeInput(session, "compgroup", choices = chc)
})
steps <- reactive({
data.frame(
element = c("#grp1 + .selectize-control",
"#compgroup + .selectize-control",
"#grp1 + .selectize-control",
"#compgroup + .selectize-control"),
intro = c("Choose x for Group 1",
"Choose two values for Comparing Groups",
"Choose y for Group 1",
"Choose two values for Comparing Groups"),
position = "right")
})
observeEvent(input$btn, introjs(session, options = list(steps=steps())))
}
# Run the application
shinyApp(ui = ui, server = server)
Это связано с тем, что introJs()
сохраняет introItems
один раз, и если затем updateSelectizeInput
выполняется во время intro
, сохраненные целевые элементы, соответствующие этому input
, устарели (хотя они имеют одинаковый id
).
Хотя эту проблему можно решить, переназначив элементы, например. для приведенного выше примера, добавив событие onChange
в introjs()
:
events = list(
onchange = I('
if (this._currentStep % 2 == 1) {
this._introItems[this._currentStep].element = $("#compgroup + .selectize-control")[0];
}
')
)
, лучшим решением может быть использование обработки на стороне сервера, т. е. мы используем updateSelectizeInput
с server = TRUE
. Тогда все заработает, пример ниже.
library(shiny)
library(rintrojs)
# Define UI for application that draws a histogram
ui <- fluidPage(# Application title
titlePanel("IntroJS Problem"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
actionButton("browser", "browser"),
introjsUI(),
actionButton("btn", "Interactive Tutorial"),
selectizeInput(
"grp1",
"Grouping Variable",
choices = c("x", "y"),
selected = "x"
),
selectizeInput(
"compgroup",
"Compare Groups (Choose 2)",
choices = "",
multiple = TRUE,
options = list(maxItems = 2)
)
),
# Show a plot of the generated distribution
mainPanel()
))
# Define server logic required to draw a histogram
server <- function(input, output, session) {
library(rintrojs)
observeEvent(input$browser, {
browser()
})
updateSelectizeInput(session, "compgroup", choices = "", server = TRUE)
chc <-
debounce(reactive(if (input$grp1 == "x") {
c("A", "B", "C")
} else {
c("D", "E", "F")
}), 200)
observe({
req(input$grp1)
updateSelectizeInput(session,
"compgroup",
choices = chc(),
server = TRUE)
})
steps <- reactive({
data.frame(
element = c(
"#grp1 + .selectize-control",
"#compgroup + .selectize-control",
"#grp1 + .selectize-control",
"#compgroup + .selectize-control"
),
intro = c(
"Choose x for Group 1",
"Choose two values for Comparing Groups",
"Choose y for Group 1",
"Choose two values for Comparing Groups"
),
position = "right"
)
})
observeEvent(input$btn, introjs(session, options = list(steps = steps())))
}
# Run the application
shinyApp(ui = ui, server = server)