Многостраничный intro.js с Shiny
Я пытаюсь реализовать многостраничную функциональность into.js в приложении Shiny.
Код ниже - попытка, которая не работает. Первая вкладка работает хорошо, всплывающее окно для второй страницы отображается, но без переключения вкладки.
ui.R
library(shiny)
shinyUI(tagList(
tags$head(
HTML("<link rel='stylesheet' type='text/css' href='css/introjs.min.css'>")
),
navbarPage("Old Faithful Geyser Data",
tabPanel(id = "fTab", "First tab",
HTML("<h1 data-step='1' data-intro='This is a tooltip!'>Basic Usage</h1>"),
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30),
plotOutput("distPlot"),
HTML("<a id='startButton' class='btn btn-large btn-success' href='javascript:void(0);'>Help</a>")
),
tabPanel(tabName = "sTab", "Second tab", id = "tt",
HTML("<h1 data-step='2' data-intro='This is a second tooltip!'>Basic Usage</h1>"),
sliderInput("bins2",
"Number of bins:",
min = 1,
max = 50,
value = 30),
plotOutput("distPlot2")
)
),
HTML("<script type='text/javascript' src='js/intro.min.js'></script>"),
HTML("<script type='text/javascript'>document.getElementById('startButton').onclick = function() {
introJs().setOption('doneLabel', 'Next page').start().oncomplete(function() {
window.location.hash = '#!tt?multipage=true';
});
};</script>")
))
server.R
library(shiny)
shinyServer(function(input, output) {
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
output$distPlot2 <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins2 + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
})
Файлы js и css из intro.js находятся в папках js и css внутри папки www. Файлы intro.js можно найти здесь
Я предполагаю, что я делаю что-то не так в функции в коде JavaScript в нижней части ui.R. Я попытался адаптировать пример отсюда, заменив window.location.href на window.location.hash и сославшись на идентификатор вкладки "tt".
2 ответа
Вот рабочее решение. Обратите внимание, что вам нужно
- Определите текущий шаг для переключения вкладок. Многостраничный пример здесь не применим, так как все ваши шаги находятся на одной странице (несколько вкладок, но одна страница), таким образом,
intro.js
покажет все шаги доnext page
нажата - Используйте JavaScript/JQuery для имитации события нажатия на вкладку.
ui.R (server.R без изменений)
library(shiny)
shinyUI(tagList(
tags$head(
HTML("<link rel='stylesheet' type='text/css' href='css/introjs.min.css'>")
),
navbarPage("Old Faithful Geyser Data",
tabPanel(id = "fTab", "First tab",
HTML("<h1 data-step='1' data-intro='This is a tooltip!'>Basic Usage</h1>"),
sliderInput("bins",
"Number of bins:",
min = 1,
max = 50,
value = 30),
plotOutput("distPlot"),
HTML("<a id='startButton' class='btn btn-large btn-success' href='javascript:void(0);'>Help</a>")
),
tabPanel(tabName = "sTab", "Second tab", id = "tt",
HTML("<h1 data-step='2' data-intro='This is a second tooltip!'>Basic Usage</h1>"),
sliderInput("bins2",
"Number of bins:",
min = 1,
max = 50,
value = 30),
plotOutput("distPlot2")
)
),
HTML("<script type='text/javascript' src='js/intro.min.js'></script>"),
HTML("<script type='text/javascript'>document.getElementById('startButton').onclick = function() {
introJs().onchange(function(targetElement) {
if (this._currentStep==0) {
$('a[data-value=\"Second tab\"]').removeClass('active');
$('a[data-value=\"First tab\"]').addClass('active');
$('a[data-value=\"First tab\"]').trigger('click');
}
if (this._currentStep==1) {
$('a[data-value=\"First tab\"]').removeClass('active');
$('a[data-value=\"Second tab\"]').addClass('active');
$('a[data-value=\"Second tab\"]').trigger('click');
}
}).start();
};</script>")
))
@warmoverflow дал отличный ответ. Вот версия того же ответа, используя rintrojs
:
library(shiny)
library(rintrojs)
ui = shinyUI(tagList(
introjsUI(),
navbarPage(
"Old Faithful Geyser Data",
tabPanel(
id = "fTab",
"First tab",
introBox(
h1("Basic Usage"),
data.step = 1,
data.intro = "This is a tooltip"
),
sliderInput(
"bins",
"Number of bins:",
min = 1,
max = 50,
value = 30
),
plotOutput("distPlot"),
actionButton("startButton", "Help")
),
tabPanel(
tabName = "sTab",
"Second tab",
id = "tt",
introBox(
h1("Basic Usage 2"),
data.step = 2,
data.intro = "This is a second tooltip"
),
sliderInput(
"bins2",
"Number of bins:",
min = 1,
max = 50,
value = 30
),
plotOutput("distPlot2")
)
)
))
server = shinyServer(function(input, output, session) {
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x,
breaks = bins,
col = 'darkgray',
border = 'white')
})
output$distPlot2 <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins2 + 1)
hist(x,
breaks = bins,
col = 'darkgray',
border = 'white')
})
observeEvent(input$startButton, {
introjs(
session,
events = list(
"onchange" = "if (this._currentStep==0) {
$('a[data-value=\"Second tab\"]').removeClass('active');
$('a[data-value=\"First tab\"]').addClass('active');
$('a[data-value=\"First tab\"]').trigger('click');
}
if (this._currentStep==1) {
$('a[data-value=\"First tab\"]').removeClass('active');
$('a[data-value=\"Second tab\"]').addClass('active');
$('a[data-value=\"Second tab\"]').trigger('click');
}"
)
)
})
})
shinyApp(ui = ui, server = server)
Вкладки не переключаются, если вы вернетесь к первому шагу тура, поэтому код работает только в дальнейшем.
ПРИМЕЧАНИЕ: в rintrojs
версия 0.1.2.900 и выше, необработанный javascript должен быть упакован в I()