Проблема с возвратом Rintrojs к элементу после обновления выбора

У меня есть блестящее приложение, которое генерирует варианты для selectizeInput() на основе значения другого селектора. В частности, он находит уникальные значения выбранной переменной и затем делает этот выбор. Я инициализирую селектор с помощью selectizeInput() в пользовательском интерфейсе, а затем использую observe({}), чтобы определить изменения во входных данных, а затем вызываю updateSelectizeInput(), чтобы изменить выбор. Все это работает нормально.

Проблема, с которой я сталкиваюсь, заключается в том, что когда я использую rintrojs, селектор вариантов определяется через приложение в первый раз, но когда варианты выбора обновляются, если я попытаюсь вернуться к ним снова, элемент не может быть найден. Вот несколько скриншотов, которые идентифицируют проблему. Во-первых, вот скриншот первого шага урока:

Проблема с возвратом Rintrojs к элементу после обновления выбора

Далее я могу выбрать два значения в селекторе групп сравнения.

Проблема с возвратом Rintrojs к элементу после обновления выбора

Затем он отправляет меня обратно, чтобы выбрать другое значение для группы 1, я выбираю «y».

Проблема с возвратом Rintrojs к элементу после обновления выбора

Наконец, когда руководство пытается вернуться к группам сравнения, оно просто перемещает всплывающую подсказку в верхний левый угол.

Проблема с возвратом Rintrojs к элементу после обновления выбора

Но с обновлением селектора проблем не возникло: вы можете видеть, что теперь он имеет значения D, E и F.

Проблема с возвратом Rintrojs к элементу после обновления выбора

Есть ли у вас идеи, почему я не могу вернуться к средству выбора групп сравнения после обновления вариантов. Как видно из кода ниже, я использую тот же идентификатор для выбора селектора группы сравнения, который работает в первый раз, но не во второй. Вот игрушечный пример.

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)
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это связано с тем, что 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)

Другие вопросы по теме